diff --git a/Cargo.lock b/Cargo.lock index c0705778..dbb2f567 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1098,9 +1098,9 @@ checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2916,9 +2916,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2926,24 +2926,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.66", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2951,22 +2951,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" diff --git a/PluralKit.API/ApiConfig.cs b/PluralKit.API/ApiConfig.cs index b3946168..fc34d515 100644 --- a/PluralKit.API/ApiConfig.cs +++ b/PluralKit.API/ApiConfig.cs @@ -5,4 +5,5 @@ public class ApiConfig public int Port { get; set; } = 5000; public string? ClientId { get; set; } public string? ClientSecret { get; set; } + public bool TrustAuth { get; set; } = false; } \ No newline at end of file diff --git a/PluralKit.API/AuthorizationTokenHandlerMiddleware.cs b/PluralKit.API/AuthorizationTokenHandlerMiddleware.cs index 3de763e0..a09c869e 100644 --- a/PluralKit.API/AuthorizationTokenHandlerMiddleware.cs +++ b/PluralKit.API/AuthorizationTokenHandlerMiddleware.cs @@ -13,19 +13,13 @@ public class AuthorizationTokenHandlerMiddleware _next = next; } - public async Task Invoke(HttpContext ctx, IDatabase db) + public async Task Invoke(HttpContext ctx, IDatabase db, ApiConfig cfg) { - ctx.Request.Headers.TryGetValue("authorization", out var authHeaders); - if (authHeaders.Count > 0) - { - var systemId = await db.Execute(conn => conn.QuerySingleOrDefaultAsync( - "select id from systems where token = @token", - new { token = authHeaders[0] } - )); - - if (systemId != null) - ctx.Items.Add("SystemId", systemId); - } + if (cfg.TrustAuth + && ctx.Request.Headers.TryGetValue("X-PluralKit-SystemId", out var sidHeaders) + && sidHeaders.Count > 0 + && int.TryParse(sidHeaders[0], out var systemId)) + ctx.Items.Add("SystemId", new SystemId(systemId)); await _next.Invoke(ctx); } diff --git a/lib/libpk/src/db/repository/auth.rs b/lib/libpk/src/db/repository/auth.rs new file mode 100644 index 00000000..b2d82fa4 --- /dev/null +++ b/lib/libpk/src/db/repository/auth.rs @@ -0,0 +1,20 @@ +pub async fn legacy_token_auth( + pool: &sqlx::postgres::PgPool, + token: &str, +) -> anyhow::Result> { + let mut system: Vec = + sqlx::query_as("select id from systems where token = $1") + .bind(token) + .fetch_all(pool) + .await?; + Ok(if let Some(system) = system.pop() { + Some(system.id) + } else { + None + }) +} + +#[derive(sqlx::FromRow)] +struct LegacyTokenDbResponse { + id: i32, +} diff --git a/lib/libpk/src/db/repository/mod.rs b/lib/libpk/src/db/repository/mod.rs index 3ff94ed1..ae0ae7b9 100644 --- a/lib/libpk/src/db/repository/mod.rs +++ b/lib/libpk/src/db/repository/mod.rs @@ -1,2 +1,5 @@ mod stats; pub use stats::*; + +mod auth; +pub use auth::*; diff --git a/services/api/src/main.rs b/services/api/src/main.rs index b87e63df..f0452e54 100644 --- a/services/api/src/main.rs +++ b/services/api/src/main.rs @@ -135,6 +135,7 @@ async fn main() -> anyhow::Result<()> { .layer(axum::middleware::from_fn(middleware::logger)) .layer(middleware::ratelimit::ratelimiter(middleware::ratelimit::do_request_ratelimited)) // this sucks + .layer(axum::middleware::from_fn_with_state(ctx.clone(), middleware::authnz)) .layer(axum::middleware::from_fn(middleware::ignore_invalid_routes)) .layer(axum::middleware::from_fn(middleware::cors)) diff --git a/services/api/src/middleware/authnz.rs b/services/api/src/middleware/authnz.rs new file mode 100644 index 00000000..e1b44941 --- /dev/null +++ b/services/api/src/middleware/authnz.rs @@ -0,0 +1,35 @@ +use axum::{ + extract::{Request, State}, + http::HeaderValue, + middleware::Next, + response::Response, +}; +use tracing::error; + +use crate::ApiContext; + +pub async fn authnz(State(ctx): State, mut request: Request, next: Next) -> Response { + let headers = request.headers_mut(); + headers.remove("x-pluralkit-systemid"); + let auth_header = headers + .get("authorization") + .map(|h| h.to_str().ok()) + .flatten(); + if let Some(auth_header) = auth_header { + if let Some(system_id) = + match libpk::db::repository::legacy_token_auth(&ctx.db, auth_header).await { + Ok(val) => val, + Err(err) => { + error!(?err, "failed to query authorization token in postgres"); + None + } + } + { + headers.append( + "x-pluralkit-systemid", + HeaderValue::from_str(format!("{system_id}").as_str()).unwrap(), + ); + } + } + next.run(request).await +} diff --git a/services/api/src/middleware/mod.rs b/services/api/src/middleware/mod.rs index 7746157c..dbdfba13 100644 --- a/services/api/src/middleware/mod.rs +++ b/services/api/src/middleware/mod.rs @@ -1,5 +1,4 @@ mod cors; - pub use cors::cors; mod logger; @@ -9,3 +8,6 @@ mod ignore_invalid_routes; pub use ignore_invalid_routes::ignore_invalid_routes; pub mod ratelimit; + +mod authnz; +pub use authnz::authnz;