remove stale dependency oxide-auth-axum

This commit is contained in:
lafleur 2025-05-09 12:08:12 +02:00 committed by Jade Ellis
parent ec2c2bb27c
commit 6c5289192d
No known key found for this signature in database
GPG key ID: 8705A2A3EBF77BD2
10 changed files with 102 additions and 84 deletions

12
Cargo.lock generated
View file

@ -877,7 +877,6 @@ dependencies = [
"itertools 0.14.0", "itertools 0.14.0",
"log", "log",
"oxide-auth", "oxide-auth",
"oxide-auth-axum",
"percent-encoding", "percent-encoding",
"rand 0.8.5", "rand 0.8.5",
"reqwest", "reqwest",
@ -1068,7 +1067,6 @@ dependencies = [
"conduwuit_service", "conduwuit_service",
"futures", "futures",
"oxide-auth", "oxide-auth",
"oxide-auth-axum",
"percent-encoding", "percent-encoding",
"rand 0.8.5", "rand 0.8.5",
"serde", "serde",
@ -3126,16 +3124,6 @@ dependencies = [
"url", "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]] [[package]]
name = "parking" name = "parking"
version = "2.2.1" version = "2.2.1"

View file

@ -543,9 +543,6 @@ version = "1.0.2"
[workspace.dependencies.oxide-auth] [workspace.dependencies.oxide-auth]
version = "0.6.1" version = "0.6.1"
[workspace.dependencies.oxide-auth-axum]
version = "0.5.0"
[workspace.dependencies.percent-encoding] [workspace.dependencies.percent-encoding]
version = "2.3.1" version = "2.3.1"

View file

@ -91,7 +91,6 @@ sha1.workspace = true
tokio.workspace = true tokio.workspace = true
tracing.workspace = true tracing.workspace = true
oxide-auth.workspace = true oxide-auth.workspace = true
oxide-auth-axum.workspace = true
conduwuit-web.workspace = true conduwuit-web.workspace = true
percent-encoding.workspace = true percent-encoding.workspace = true

View file

@ -1,5 +1,4 @@
use conduwuit_web::oidc::{oidc_consent_form, oidc_login_form, AuthorizationQuery, OidcRequest, OidcResponse}; use conduwuit_web::oidc::{oidc_consent_form, oidc_login_form, AuthorizationQuery, OidcRequest, OidcResponse};
use oxide_auth_axum::{OAuthResponse, OAuthRequest};
use oxide_auth::{ use oxide_auth::{
endpoint::{OwnerConsent, Solicitation}, endpoint::{OwnerConsent, Solicitation},
frontends::simple::endpoint::FnSolicitor, frontends::simple::endpoint::FnSolicitor,
@ -78,8 +77,8 @@ pub(crate) struct Allowance {
pub(crate) async fn authorize_consent( pub(crate) async fn authorize_consent(
Query(Allowance { allow }): Query<Allowance>, Query(Allowance { allow }): Query<Allowance>,
State(services): State<crate::State>, State(services): State<crate::State>,
oauth: OAuthRequest, oauth: OidcRequest,
) -> Result<OAuthResponse> { ) -> Result<OidcResponse> {
let allowed = allow.unwrap_or(false); let allowed = allow.unwrap_or(false);
tracing::debug!("processing user's consent: {:?} - {:?}", allowed, oauth); tracing::debug!("processing user's consent: {:?} - {:?}", allowed, oauth);

View file

@ -1,10 +1,7 @@
use oxide_auth_axum::{OAuthResponse, OAuthRequest}; use conduwuit_web::oidc::{OidcRequest, OidcResponse};
use oxide_auth::endpoint::QueryParameter;
use axum::{
extract::State,
response::IntoResponse,
};
use conduwuit::{Result, err}; use conduwuit::{Result, err};
use oxide_auth::endpoint::QueryParameter;
use axum::extract::State;
/// # `POST /_matrix/client/unstable/org.matrix.msc2964/token` /// # `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. /// it in the server's ring, or refresh the token.
pub(crate) async fn token( pub(crate) async fn token(
State(services): State<crate::State>, State(services): State<crate::State>,
oauth: OAuthRequest, oauth: OidcRequest,
) -> Result<OAuthResponse> { ) -> Result<OidcResponse> {
let Some(body) = oauth.body() else { let Some(body) = oauth.body() else {
return Err(err!(Request(Unknown("OAuth request had an empty body")))); 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:?}")))), 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<crate::State>,
oauth: OAuthRequest,
) -> impl IntoResponse {
const DENY_TEXT: &str = "<html>
This page should be accessed via an oauth token from the client in the example. Click
<a href=\"/authorize?response_type=code&client_id=LocalClient\">
here</a> to begin the authorization process.
</html>
";
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:?}"))))),
}
}

View file

@ -36,7 +36,6 @@ serde.workspace = true
url.workspace = true url.workspace = true
percent-encoding.workspace = true percent-encoding.workspace = true
oxide-auth.workspace = true oxide-auth.workspace = true
oxide-auth-axum.workspace = true
[lints] [lints]
workspace = true workspace = true

View file

@ -7,11 +7,13 @@ use crate::{
mod authorize; mod authorize;
mod consent; mod consent;
mod error;
mod login; mod login;
mod response; mod response;
mod request; mod request;
pub use authorize::AuthorizationQuery; pub use authorize::AuthorizationQuery;
pub use consent::oidc_consent_form; pub use consent::oidc_consent_form;
pub use error::OidcError;
pub use login::{LoginQuery, LoginError, oidc_login_form}; pub use login::{LoginQuery, LoginError, oidc_login_form};
pub use request::OidcRequest; pub use request::OidcRequest;
pub use response::OidcResponse; pub use response::OidcResponse;

80
src/web/oidc/error.rs Normal file
View file

@ -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<String>),
}
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<Error<OidcRequest>> for OidcError {
fn from(e: Error<OidcRequest>) -> Self {
match e {
Error::Web(e) => e,
Error::OAuth(e) => e.into(),
}
}
}
impl From<OAuthError> for OidcError {
fn from(e: OAuthError) -> Self {
OidcError::Endpoint(e)
}
}
impl From<InvalidHeaderValue> for OidcError {
fn from(e: InvalidHeaderValue) -> Self {
Self::Header(e)
}
}

View file

@ -1,6 +1,5 @@
use super::OidcResponse; use super::{OidcError, OidcResponse};
use oxide_auth::endpoint::{NormalizedParameter, QueryParameter, WebRequest}; use oxide_auth::endpoint::{NormalizedParameter, QueryParameter, WebRequest};
use oxide_auth_axum::WebError;
use async_trait::async_trait; use async_trait::async_trait;
use axum::{ use axum::{
extract::{Form, FromRequest, FromRequestParts, Query, Request}, extract::{Form, FromRequest, FromRequestParts, Query, Request},
@ -45,21 +44,21 @@ impl OidcRequest {
} }
impl WebRequest for OidcRequest { impl WebRequest for OidcRequest {
type Error = WebError; type Error = OidcError;
type Response = OidcResponse; type Response = OidcResponse;
fn query(&mut self) -> Result<Cow<'_, dyn QueryParameter + 'static>, Self::Error> { fn query(&mut self) -> Result<Cow<'_, dyn QueryParameter + 'static>, Self::Error> {
self.query self.query
.as_ref() .as_ref()
.map(|q| Cow::Borrowed(q as &dyn QueryParameter)) .map(|q| Cow::Borrowed(q as &dyn QueryParameter))
.ok_or(WebError::Query) .ok_or(OidcError::Query)
} }
fn urlbody(&mut self) -> Result<Cow<'_, dyn QueryParameter + 'static>, Self::Error> { fn urlbody(&mut self) -> Result<Cow<'_, dyn QueryParameter + 'static>, Self::Error> {
self.body self.body
.as_ref() .as_ref()
.map(|b| Cow::Borrowed(b as &dyn QueryParameter)) .map(|b| Cow::Borrowed(b as &dyn QueryParameter))
.ok_or(WebError::Body) .ok_or(OidcError::Body)
} }
fn authheader(&mut self) -> Result<Option<Cow<'_, str>>, Self::Error> { fn authheader(&mut self) -> Result<Option<Cow<'_, str>>, Self::Error> {
@ -72,14 +71,14 @@ impl<S> FromRequest<S> for OidcRequest
where where
S: Send + Sync, S: Send + Sync,
{ {
type Rejection = WebError; type Rejection = OidcError;
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> { async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let mut all_auth = req.headers().get_all(header::AUTHORIZATION).iter(); let mut all_auth = req.headers().get_all(header::AUTHORIZATION).iter();
let optional = all_auth.next(); let optional = all_auth.next();
let auth = if all_auth.next().is_some() { let auth = if all_auth.next().is_some() {
return Err(WebError::Authorization); return Err(OidcError::Authorization);
} else { } else {
optional.and_then(|hv| hv.to_str().ok().map(str::to_owned)) optional.and_then(|hv| hv.to_str().ok().map(str::to_owned))
}; };

View file

@ -1,14 +1,11 @@
use super::{OidcRequest, oidc_consent_form}; use super::{oidc_consent_form, LoginQuery, OidcError, OidcRequest};
use crate::oidc::LoginQuery;
use oxide_auth::{ use oxide_auth::{
endpoint::{OwnerConsent, OwnerSolicitor, Solicitation, WebRequest, WebResponse}, endpoint::{OwnerConsent, OwnerSolicitor, Solicitation, WebRequest, WebResponse},
frontends::simple::request::{Body as OAuthRequestBody, Status}, frontends::simple::request::{Body as OAuthRequestBody, Status},
}; };
use oxide_auth_axum::WebError;
use axum::{ use axum::{
body::Body, body::Body,
http::{Response, header}, http::{header, Response},
response::IntoResponse, response::IntoResponse,
}; };
use url::Url; use url::Url;
@ -26,7 +23,7 @@ pub struct OidcResponse {
impl OidcResponse { impl OidcResponse {
/// Instanciate from a response body. Used to send login or consent forms. /// Instanciate from a response body. Used to send login or consent forms.
pub fn from_body(body: &str) -> Result<Self, WebError> { pub fn from_body(body: &str) -> Result<Self, OidcError> {
let mut result = OidcResponse::default(); let mut result = OidcResponse::default();
result.body_text(body)?; 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<OidcRequest> for OidcResponse { impl OwnerSolicitor<OidcRequest> for OidcResponse {
fn check_consent( fn check_consent(
&mut self, &mut self,
request: &mut OidcRequest, request: &mut OidcRequest,
_: Solicitation<'_>, _: Solicitation<'_>,
) -> OwnerConsent<<OidcRequest as WebRequest>::Response> { ) -> OwnerConsent<<OidcRequest as WebRequest>::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 = "Continuwuity";
/*
let hostname = request
.query()
.expect("query in OAuth request")
.unique_value("hostname")
.expect("hostname in OAuth request")
.as_str();
*/
let query: LoginQuery = request let query: LoginQuery = request
.clone() .clone()
.try_into() .try_into()
@ -79,7 +70,7 @@ impl OwnerSolicitor<OidcRequest> for OidcResponse {
} }
impl WebResponse for OidcResponse { impl WebResponse for OidcResponse {
type Error = WebError; type Error = OidcError;
fn ok(&mut self) -> Result<(), Self::Error> { fn ok(&mut self) -> Result<(), Self::Error> {
self.status = Status::Ok; self.status = Status::Ok;