From 6c5289192d81e2136b9d6cfa2febfc07f767c6b3 Mon Sep 17 00:00:00 2001 From: lafleur Date: Fri, 9 May 2025 12:08:12 +0200 Subject: [PATCH] remove stale dependency oxide-auth-axum --- Cargo.lock | 12 ----- Cargo.toml | 3 -- src/api/Cargo.toml | 1 - src/api/client/oidc/authorize.rs | 5 +- src/api/client/oidc/token.rs | 46 ++---------------- src/web/Cargo.toml | 1 - src/web/oidc.rs | 2 + src/web/oidc/error.rs | 80 ++++++++++++++++++++++++++++++++ src/web/oidc/request.rs | 13 +++--- src/web/oidc/response.rs | 23 +++------ 10 files changed, 102 insertions(+), 84 deletions(-) create mode 100644 src/web/oidc/error.rs diff --git a/Cargo.lock b/Cargo.lock index 6b45da79..fbbf35c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -877,7 +877,6 @@ dependencies = [ "itertools 0.14.0", "log", "oxide-auth", - "oxide-auth-axum", "percent-encoding", "rand 0.8.5", "reqwest", @@ -1068,7 +1067,6 @@ dependencies = [ "conduwuit_service", "futures", "oxide-auth", - "oxide-auth-axum", "percent-encoding", "rand 0.8.5", "serde", @@ -3126,16 +3124,6 @@ dependencies = [ "url", ] -[[package]] -name = "oxide-auth-axum" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65f0303e212596cb24ba33f4a7ae8f69e84596bea5fc65d089de65b09bfbcb8" -dependencies = [ - "axum", - "oxide-auth", -] - [[package]] name = "parking" version = "2.2.1" diff --git a/Cargo.toml b/Cargo.toml index 7750253c..0978a45c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -543,9 +543,6 @@ version = "1.0.2" [workspace.dependencies.oxide-auth] version = "0.6.1" -[workspace.dependencies.oxide-auth-axum] -version = "0.5.0" - [workspace.dependencies.percent-encoding] version = "2.3.1" diff --git a/src/api/Cargo.toml b/src/api/Cargo.toml index 3ddb0f0d..3b4e4d51 100644 --- a/src/api/Cargo.toml +++ b/src/api/Cargo.toml @@ -91,7 +91,6 @@ sha1.workspace = true tokio.workspace = true tracing.workspace = true oxide-auth.workspace = true -oxide-auth-axum.workspace = true conduwuit-web.workspace = true percent-encoding.workspace = true diff --git a/src/api/client/oidc/authorize.rs b/src/api/client/oidc/authorize.rs index 12a1ab79..697e684b 100644 --- a/src/api/client/oidc/authorize.rs +++ b/src/api/client/oidc/authorize.rs @@ -1,5 +1,4 @@ use conduwuit_web::oidc::{oidc_consent_form, oidc_login_form, AuthorizationQuery, OidcRequest, OidcResponse}; -use oxide_auth_axum::{OAuthResponse, OAuthRequest}; use oxide_auth::{ endpoint::{OwnerConsent, Solicitation}, frontends::simple::endpoint::FnSolicitor, @@ -78,8 +77,8 @@ pub(crate) struct Allowance { pub(crate) async fn authorize_consent( Query(Allowance { allow }): Query, State(services): State, - oauth: OAuthRequest, -) -> Result { + oauth: OidcRequest, +) -> Result { let allowed = allow.unwrap_or(false); tracing::debug!("processing user's consent: {:?} - {:?}", allowed, oauth); diff --git a/src/api/client/oidc/token.rs b/src/api/client/oidc/token.rs index 543ac9bb..80809c98 100644 --- a/src/api/client/oidc/token.rs +++ b/src/api/client/oidc/token.rs @@ -1,10 +1,7 @@ -use oxide_auth_axum::{OAuthResponse, OAuthRequest}; -use oxide_auth::endpoint::QueryParameter; -use axum::{ - extract::State, - response::IntoResponse, -}; +use conduwuit_web::oidc::{OidcRequest, OidcResponse}; use conduwuit::{Result, err}; +use oxide_auth::endpoint::QueryParameter; +use axum::extract::State; /// # `POST /_matrix/client/unstable/org.matrix.msc2964/token` /// @@ -12,8 +9,8 @@ use conduwuit::{Result, err}; /// it in the server's ring, or refresh the token. pub(crate) async fn token( State(services): State, - oauth: OAuthRequest, -) -> Result { + oauth: OidcRequest, +) -> Result { let Some(body) = oauth.body() else { return Err(err!(Request(Unknown("OAuth request had an empty body")))); }; @@ -37,36 +34,3 @@ pub(crate) async fn token( Err(err!(Request(Unknown("unsupported grant type: {other:?}")))), } } - -/// Sample protected content. TODO check that resources are available with the returned token. -pub(crate) async fn _protected_resource( - State(services): State, - oauth: OAuthRequest, -) -> impl IntoResponse { - const DENY_TEXT: &str = " -This page should be accessed via an oauth token from the client in the example. Click - -here to begin the authorization process. - -"; - - let protect = services - .oidc - .endpoint() - .with_scopes(vec!["default-scope".parse().unwrap()]) - .resource_flow() - .execute(oauth); - match protect { - Ok(_grant) => Ok("Hello, world"), - Err(Ok(response)) => { - let error: OAuthResponse = response - //.header(ContentType::HTML) - .body(DENY_TEXT) - //.finalize() - .into(); - Err(Ok(error)) - } - Err(Err(err)) => Err(Err(err!(Request(Unknown("auth failed: {err:?}"))))), - } -} - diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 2076a990..15ea1f1d 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -36,7 +36,6 @@ serde.workspace = true url.workspace = true percent-encoding.workspace = true oxide-auth.workspace = true -oxide-auth-axum.workspace = true [lints] workspace = true diff --git a/src/web/oidc.rs b/src/web/oidc.rs index 97d0099c..dfda7103 100644 --- a/src/web/oidc.rs +++ b/src/web/oidc.rs @@ -7,11 +7,13 @@ use crate::{ mod authorize; mod consent; +mod error; mod login; mod response; mod request; pub use authorize::AuthorizationQuery; pub use consent::oidc_consent_form; +pub use error::OidcError; pub use login::{LoginQuery, LoginError, oidc_login_form}; pub use request::OidcRequest; pub use response::OidcResponse; diff --git a/src/web/oidc/error.rs b/src/web/oidc/error.rs new file mode 100644 index 00000000..81513814 --- /dev/null +++ b/src/web/oidc/error.rs @@ -0,0 +1,80 @@ +use super::OidcRequest; +use axum::{ + http::{header::InvalidHeaderValue, StatusCode}, + response::{IntoResponse, Response}, +}; +use oxide_auth::frontends::{dev::OAuthError, simple::endpoint::Error}; + +#[derive(Debug)] +/// The error type for Oxide Auth operations +pub enum OidcError { + /// Errors occuring in Endpoint operations + Endpoint(OAuthError), + /// Errors occuring in Endpoint operations + Header(InvalidHeaderValue), + /// Errors with the request encoding + Encoding, + /// Request body could not be parsed as a form + Form, + /// Request query was absent or could not be parsed + Query, + /// Request query was absent or could not be parsed + Body, + /// The Authorization header was invalid + Authorization, + /// General internal server error + InternalError(Option), +} + +impl std::fmt::Display for OidcError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + OidcError::Endpoint(ref e) => write!(f, "Endpoint, {}", e), + OidcError::Header(ref e) => write!(f, "Couldn't set header, {}", e), + OidcError::Encoding => write!(f, "Error decoding request"), + OidcError::Form => write!(f, "Request is not a form"), + OidcError::Query => write!(f, "No query present"), + OidcError::Body => write!(f, "No body present"), + OidcError::Authorization => write!(f, "Request has invalid Authorization headers"), + OidcError::InternalError(None) => write!(f, "An internal server error occured"), + OidcError::InternalError(Some(ref e)) => write!(f, "An internal server error occured: {}", e), + } + } +} + +impl std::error::Error for OidcError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match *self { + OidcError::Endpoint(ref e) => e.source(), + OidcError::Header(ref e) => e.source(), + _ => None, + } + } +} + +impl IntoResponse for OidcError { + fn into_response(self) -> Response { + (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()).into_response() + } +} + +impl From> for OidcError { + fn from(e: Error) -> Self { + match e { + Error::Web(e) => e, + Error::OAuth(e) => e.into(), + } + } +} + +impl From for OidcError { + fn from(e: OAuthError) -> Self { + OidcError::Endpoint(e) + } +} + +impl From for OidcError { + fn from(e: InvalidHeaderValue) -> Self { + Self::Header(e) + } +} diff --git a/src/web/oidc/request.rs b/src/web/oidc/request.rs index 2417b3bf..b8301eb1 100644 --- a/src/web/oidc/request.rs +++ b/src/web/oidc/request.rs @@ -1,6 +1,5 @@ -use super::OidcResponse; +use super::{OidcError, OidcResponse}; use oxide_auth::endpoint::{NormalizedParameter, QueryParameter, WebRequest}; -use oxide_auth_axum::WebError; use async_trait::async_trait; use axum::{ extract::{Form, FromRequest, FromRequestParts, Query, Request}, @@ -45,21 +44,21 @@ impl OidcRequest { } impl WebRequest for OidcRequest { - type Error = WebError; + type Error = OidcError; type Response = OidcResponse; fn query(&mut self) -> Result, Self::Error> { self.query .as_ref() .map(|q| Cow::Borrowed(q as &dyn QueryParameter)) - .ok_or(WebError::Query) + .ok_or(OidcError::Query) } fn urlbody(&mut self) -> Result, Self::Error> { self.body .as_ref() .map(|b| Cow::Borrowed(b as &dyn QueryParameter)) - .ok_or(WebError::Body) + .ok_or(OidcError::Body) } fn authheader(&mut self) -> Result>, Self::Error> { @@ -72,14 +71,14 @@ impl FromRequest for OidcRequest where S: Send + Sync, { - type Rejection = WebError; + type Rejection = OidcError; async fn from_request(req: Request, state: &S) -> Result { let mut all_auth = req.headers().get_all(header::AUTHORIZATION).iter(); let optional = all_auth.next(); let auth = if all_auth.next().is_some() { - return Err(WebError::Authorization); + return Err(OidcError::Authorization); } else { optional.and_then(|hv| hv.to_str().ok().map(str::to_owned)) }; diff --git a/src/web/oidc/response.rs b/src/web/oidc/response.rs index 08a44e65..87a61b00 100644 --- a/src/web/oidc/response.rs +++ b/src/web/oidc/response.rs @@ -1,14 +1,11 @@ -use super::{OidcRequest, oidc_consent_form}; - -use crate::oidc::LoginQuery; +use super::{oidc_consent_form, LoginQuery, OidcError, OidcRequest}; use oxide_auth::{ endpoint::{OwnerConsent, OwnerSolicitor, Solicitation, WebRequest, WebResponse}, frontends::simple::request::{Body as OAuthRequestBody, Status}, }; -use oxide_auth_axum::WebError; use axum::{ body::Body, - http::{Response, header}, + http::{header, Response}, response::IntoResponse, }; use url::Url; @@ -26,7 +23,7 @@ pub struct OidcResponse { impl OidcResponse { /// Instanciate from a response body. Used to send login or consent forms. - pub fn from_body(body: &str) -> Result { + pub fn from_body(body: &str) -> Result { let mut result = OidcResponse::default(); result.body_text(body)?; @@ -50,22 +47,16 @@ impl IntoResponse for OidcResponse { } } +/// OidcResponse uses [super::oidc_consent_form] to be turned into an owner +/// consent solicitation. impl OwnerSolicitor for OidcResponse { fn check_consent( &mut self, request: &mut OidcRequest, _: Solicitation<'_>, ) -> OwnerConsent<::Response> { - //let hostname = self.location.map(|l| l.as_str()).unwrap_or("Continuwuity"); + // TODO find a way to pass the hostname to the template. let hostname = "Continuwuity"; - /* - let hostname = request - .query() - .expect("query in OAuth request") - .unique_value("hostname") - .expect("hostname in OAuth request") - .as_str(); - */ let query: LoginQuery = request .clone() .try_into() @@ -79,7 +70,7 @@ impl OwnerSolicitor for OidcResponse { } impl WebResponse for OidcResponse { - type Error = WebError; + type Error = OidcError; fn ok(&mut self) -> Result<(), Self::Error> { self.status = Status::Ok;