#[non_exhaustive]pub struct User { /* private fields */ }Expand description
Who a request to a route of your own is, authenticated as REST does.
use axum::{extract::State, Json};
use postrust_server::{AppState, User};
use serde_json::{json, Value};
use std::sync::Arc;
async fn summary(
user: User,
State(state): State<Arc<AppState>>,
) -> Result<Json<Value>, postrust_server::Error> {
let mut tx = state.begin_as(&user).await?;
let n: i64 = sqlx::query_scalar("select count(*) from todos")
.fetch_one(&mut *tx)
.await?;
tx.commit().await?;
Ok(Json(json!({ "todos": n })))
}As an extractor, User reads the Authorization header. A request with
no token is the anonymous role (PGRST_DB_ANON_ROLE), or refused with
PostgREST’s 401 where there is none; a token that does not verify is
refused with the status and body the API gives it – PGRST301, PGRST303 and
the rest, with the WWW-Authenticate challenge.
§Option<User>
Option<User> is for a route that does something different for a caller
who has not signed in, whatever the server’s anonymous role: it is None
when the request sends no Authorization header at all, and Some with
the token’s user when it sends one that verifies. A token that does not
verify is still refused, not read as None: a client whose token has
expired should be told so, not quietly answered as somebody else. A route
that wants the anonymous role for a request with no token takes User
itself; see User::is_anonymous.
§What else it carries
What REST tells the database about a request besides who sent it, so that
a policy or function reading request.headers, request.cookies,
request.method, request.path or request.trace_id sees the same thing
in a transaction of yours that it sees in REST’s:
- the method, and the path as the client sent it – with the prefix your
router was nested at, where REST’s
request.pathis without/api, since that prefix is the API’s mount rather than part of the resource; - every header, by its lowercase name, and the cookies;
- the trace the request belongs to, from the server’s request span.
Not the schema a Accept-Profile header names, nor the time zone a
Prefer: timezone asks for: those are REST’s request syntax, and a route
of yours has its own. Its transaction’s search_path starts at the default
schema.
Implementations§
Source§impl User
impl User
Sourcepub fn role(&self) -> &str
pub fn role(&self) -> &str
The database role the request runs as: the token’s role claim, or the anonymous role.
Sourcepub fn claims(&self) -> &HashMap<String, Value>
pub fn claims(&self) -> &HashMap<String, Value>
The token’s claims, every one of them, as request.jwt.claims carries
them. Empty for an anonymous request.
Sourcepub fn is_anonymous(&self) -> bool
pub fn is_anonymous(&self) -> bool
Whether the request sent no token, and runs as the anonymous role.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for User
impl RefUnwindSafe for User
impl Send for User
impl Sync for User
impl Unpin for User
impl UnsafeUnpin for User
impl UnwindSafe for User
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<S, T> FromRequest<S, ViaParts> for T
impl<S, T> FromRequest<S, ViaParts> for T
Source§type Rejection = <T as FromRequestParts<S>>::Rejection
type Rejection = <T as FromRequestParts<S>>::Rejection
Source§fn from_request(
req: Request<Body>,
state: &S,
) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>>
fn from_request( req: Request<Body>, state: &S, ) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>>
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more