Only allow last extractor to mutate the request (#1272)

* Only allow last extractor to mutate the request

* Change `FromRequest` and add `FromRequestParts` trait (#1275)

* Add `Once`/`Mut` type parameter for `FromRequest` and `RequestParts`

* 🪄

* split traits

* `FromRequest` for tuples

* Remove `BodyAlreadyExtracted`

* don't need fully qualified path

* don't export `Once` and `Mut`

* remove temp tests

* depend on axum again

Co-authored-by: Jonas Platte <[email protected]>

* Port `Handler` and most extractors (#1277)

* Port `Handler` and most extractors

* Put `M` inside `Handler` impls, not trait itself

* comment out tuples for now

* fix lints

* Reorder arguments to `Handler` (#1281)

I think `Request<B>, Arc<S>` is better since its consistent with
`FromRequest` and `FromRequestParts`.

* Port most things in axum-extra (#1282)

* Port `#[derive(TypedPath)]` and `#[debug_handler]` (#1283)

* port #[derive(TypedPath)]

* wip: #[debug_handler]

* fix #[debug_handler]

* don't need itertools

* also require `Send`

* update expected error

* support fully qualified `self`

* Implement FromRequest[Parts] for tuples (#1286)

* Port docs for axum and axum-core (#1285)

* Port axum-extra (#1287)

* Port axum-extra

* Update axum-core/Cargo.toml

Co-authored-by: Jonas Platte <[email protected]>

* remove `impl FromRequest for Either*`

Co-authored-by: Jonas Platte <[email protected]>

* New FromRequest[Parts] trait cleanup (#1288)

* Make private module truly private again

* Simplify tuple FromRequest implementation

* Port `#[derive(FromRequest)]` (#1289)

* fix tests

* fix docs

* revert examples

* fix docs link

* fix intra docs links

* Port examples (#1291)

* Document wrapping other extractors (#1292)

* axum-extra doesn't need to depend on axum-core (#1294)

Missed this in https://github.com/tokio-rs/axum/pull/1287

* Add `FromRequest` changes to changelogs (#1293)

* Update changelog

* Remove default type for `S` in `Handler`

* Clarify which types have default types for `S`

* Apply suggestions from code review

Co-authored-by: Jonas Platte <[email protected]>

Co-authored-by: Jonas Platte <[email protected]>

* remove unused import

* Rename `Mut` and `Once` (#1296)

* fix trybuild expected output

Co-authored-by: Jonas Platte <[email protected]>
This commit is contained in:
David Pedersen
2022-08-22 12:23:20 +02:00
committed by GitHub
co-authored by Jonas Platte
parent f1769e5134
commit be624306f4
104 changed files with 1513 additions and 1936 deletions
+9 -9
View File
@@ -12,15 +12,14 @@ use async_session::{MemoryStore, Session, SessionStore};
use axum::{
async_trait,
extract::{
rejection::TypedHeaderRejectionReason, FromRef, FromRequest, Query, RequestParts, State,
TypedHeader,
rejection::TypedHeaderRejectionReason, FromRef, FromRequestParts, Query, State, TypedHeader,
},
http::{header::SET_COOKIE, HeaderMap},
response::{IntoResponse, Redirect, Response},
routing::get,
Router,
};
use http::header;
use http::{header, request::Parts};
use oauth2::{
basic::BasicClient, reqwest::async_http_client, AuthUrl, AuthorizationCode, ClientId,
ClientSecret, CsrfToken, RedirectUrl, Scope, TokenResponse, TokenUrl,
@@ -139,7 +138,7 @@ async fn discord_auth(State(client): State<BasicClient>) -> impl IntoResponse {
.url();
// Redirect to Discord's oauth service
Redirect::to(&auth_url.to_string())
Redirect::to(auth_url.as_ref())
}
// Valid user session required. If there is none, redirect to the auth page
@@ -224,17 +223,18 @@ impl IntoResponse for AuthRedirect {
}
#[async_trait]
impl<B> FromRequest<AppState, B> for User
impl<S> FromRequestParts<S> for User
where
B: Send,
MemoryStore: FromRef<S>,
S: Send + Sync,
{
// If anything goes wrong or no session is found, redirect to the auth page
type Rejection = AuthRedirect;
async fn from_request(req: &mut RequestParts<AppState, B>) -> Result<Self, Self::Rejection> {
let store = req.state().clone().store;
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let store = MemoryStore::from_ref(state);
let cookies = TypedHeader::<headers::Cookie>::from_request(req)
let cookies = TypedHeader::<headers::Cookie>::from_request_parts(parts, state)
.await
.map_err(|e| match *e.name() {
header::COOKIE => match e.reason() {