arminius_server_client/
client_request.rs1use arminius_lib_authentication::AuthenticatedClaims;
8use arminius_lib_component::{
9 ServerState,
10 error::MatrixApiError,
11 ruma_requests::{ParseRequestError, extract_ruma_request, to_vector_request},
12};
13use axum::extract::{FromRequestParts as _, Request};
14use ruma::api::{
15 Metadata,
16 auth_scheme::{AccessToken, AccessTokenOptional, AppserviceTokenOptional, NoAccessToken},
17};
18
19#[derive(MatrixApiError, thiserror::Error, Debug)]
21pub enum AuthenticatedRequestError {
22 #[error(transparent)]
24 AuthError(#[from] arminius_lib_authentication::AuthError),
25 #[error(transparent)]
27 ParseRequestError(#[from] ParseRequestError),
28}
29
30#[derive(Debug)]
36pub struct AuthenticatedClientRequest<T: ruma::api::IncomingRequest>(
37 pub arminius_lib_authentication::SessionInfo,
38 pub T,
39);
40
41impl<T: ruma::api::IncomingRequest> axum::extract::FromRequest<ServerState>
42 for AuthenticatedClientRequest<T>
43where
44 <T as Metadata>::Authentication: From<AccessToken> + Into<AccessToken>,
46{
47 type Rejection = AuthenticatedRequestError;
48 async fn from_request(
49 request: Request,
50 state: &ServerState,
51 ) -> Result<Self, AuthenticatedRequestError> {
52 let (mut parts, body) = request.into_parts();
53 let AuthenticatedClaims(session_info) =
54 AuthenticatedClaims::from_request_parts(&mut parts, state).await?;
55 let request = Request::from_parts(parts, body);
56 let request = to_vector_request(request).await?;
57 Ok(Self(session_info, extract_ruma_request(request).await?))
58 }
59}
60
61#[expect(dead_code, reason = "This might be used in the future")]
67#[derive(Debug)]
68pub struct OptionallyAuthenticatedClientRequest<T: ruma::api::IncomingRequest>(
69 pub Option<arminius_lib_authentication::SessionInfo>,
70 pub T,
71);
72
73impl<T: ruma::api::IncomingRequest> axum::extract::FromRequest<ServerState>
74 for OptionallyAuthenticatedClientRequest<T>
75where
76 <T as Metadata>::Authentication: From<AccessTokenOptional> + Into<AccessTokenOptional>,
78{
79 type Rejection = AuthenticatedRequestError;
80 async fn from_request(
81 request: Request,
82 state: &ServerState,
83 ) -> Result<Self, AuthenticatedRequestError> {
84 let (mut parts, body) = request.into_parts();
85 let claims = if parts.headers.contains_key("Authorization") {
86 Some(AuthenticatedClaims::from_request_parts(&mut parts, state).await?.0)
87 } else {
88 None
89 };
90 let request = Request::from_parts(parts, body);
91 let request = to_vector_request(request).await?;
92 Ok(Self(claims, extract_ruma_request(request).await?))
93 }
94}
95
96#[derive(Debug)]
102pub struct UnauthenticatedClientRequest<T: ruma::api::IncomingRequest>(pub T);
103
104impl<T: ruma::api::IncomingRequest> axum::extract::FromRequest<ServerState>
105 for UnauthenticatedClientRequest<T>
106where
107 <T as Metadata>::Authentication: From<NoAccessToken> + Into<NoAccessToken>,
109{
110 type Rejection = AuthenticatedRequestError;
111 async fn from_request(
112 request: Request,
113 _: &ServerState,
114 ) -> Result<Self, AuthenticatedRequestError> {
115 let request = to_vector_request(request).await?;
116 Ok(Self(extract_ruma_request(request).await?))
117 }
118}
119
120#[derive(Debug)]
126pub struct AppserviceTokenOptionalClientRequest<T: ruma::api::IncomingRequest>(pub T);
127
128impl<T: ruma::api::IncomingRequest> axum::extract::FromRequest<ServerState>
129 for AppserviceTokenOptionalClientRequest<T>
130where
131 <T as Metadata>::Authentication: From<AppserviceTokenOptional> + Into<AppserviceTokenOptional>,
133{
134 type Rejection = AuthenticatedRequestError;
135 async fn from_request(
136 request: Request,
137 _: &ServerState,
138 ) -> Result<Self, AuthenticatedRequestError> {
139 let request = to_vector_request(request).await?;
140 Ok(Self(extract_ruma_request(request).await?))
141 }
142}