Skip to main content

UserApproval

Struct UserApproval 

Source
pub struct UserApproval<'a> { /* private fields */ }
Expand description

A statement, by the HOST, that a resource owner saw one validated authorization request and agreed to it. The only thing AuthorizationServer::issue_authorization_code will mint from.

§Why this type exists

The http feature’s ServiceBuilder REFUSES TO BUILD without a consent resolver, so a host on that path cannot reach code issuance without having written the word “approve”. The direct API had no such step, and the direct API is the path this crate’s DEFAULT BUILD invites: no HTTP surface, no listener, the host owning its own routes. issue_authorization_code(&validated, "alice") read like a lookup, compiled, passed the host’s own tests, and shipped an authorization server that approved everything. The refusal existed on one of two supported adoption paths, which is the same as not existing.

§What it is, and what it is not

It is NOT a proof, and no type this crate could define would be one: this library has no user, no session and no screen, so “the user agreed” is a fact only the host holds. Nor is it weaker than the seam it mirrors. A host can wire |_| ApprovalDecision::Approve into the http path just as it can call UserApproval::granted here, so what BOTH seams buy is the same and is the whole of what a library at this boundary can buy: the approval becomes a sentence the host WROTE rather than a default it inherited, and the host that never considered RFC 6749 section 10.12 gets a compile error naming it instead of a working forgery endpoint.

It also closes a bug class the two-argument form left open. The approval BORROWS the request it approves, so there is no second request parameter left to disagree with it: a host cannot prompt for one request and issue for another, approving a read and minting a read write.

§Allocation

A borrow plus the subject String, which is the same one allocation the old subject: impl Into<String> argument made on its way into the record. Nothing on the token path changes, and nothing here is on it.

Implementations§

Source§

impl<'a> UserApproval<'a>

Source

pub fn granted( request: &'a ValidatedAuthorizationRequest, subject: impl Into<String>, ) -> Self

The resource owner named by subject approved request.

CALLING THIS IS AN ASSERTION. It says a real user was really asked about really this request, in whatever the deployment’s consent step is, and said yes. This crate cannot check that and will not try; what it can do is refuse to mint anything until someone writes it.

subject is the authenticated resource owner, in the host’s own vocabulary for users, and is what the issued code and every token it mints will carry.

Source

pub fn granted_at( request: &'a ValidatedAuthorizationRequest, subject: impl Into<String>, decided_at: SystemTime, ) -> Self

The same approval, dated.

WHAT THIS IS FOR, and it is not bookkeeping. A revocation barrier refuses a write whose GRANT predates the revocation, and the grant instant a code carries is the instant of the decision it rests on. For a host that prompted the user during this request those are the same moment and UserApproval::granted is right. For a host acting on a STANDING approval — a remembered consent it read at the top of the request — they are not, and dating a months-old approval at this instant makes it outrank a withdrawal recorded in between.

The failure that costs is precise. The user opens the authorization page; the host reads their standing consent; the user, elsewhere, clicks “remove this application”, and the withdrawal cascades away every token and records its barrier; the first request then resumes and mints a code on the strength of the pre-withdrawal snapshot. Nothing refuses the code — put_authorization_code is deliberately barrier-exempt — and at redemption a code dated NOW postdates the barrier, so the token is issued and its refresh chain inherits the same instant, rotating happily long after the barrier is swept.

Pass the instant the decision was made: the standing record’s own granted_at, or the instant the request was received, whichever the host can honestly claim. Both are earlier than any withdrawal that has not yet been read, which is the whole of what is needed.

Source

pub fn decided_at(&self) -> Option<SystemTime>

When the decision was made, if the host said. See UserApproval::granted_at.

Source

pub fn request(&self) -> &'a ValidatedAuthorizationRequest

The request this approves.

Source

pub fn subject(&self) -> &str

The resource owner who approved it.

Trait Implementations§

Source§

impl Debug for UserApproval<'_>

Hand-written: subject is a user identifier, and this crate does not print those into whatever caught a {:?}. Which REQUEST is being approved stays visible, because that is the whole of what anybody debugging an issuance needs.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for UserApproval<'a>

§

impl<'a> RefUnwindSafe for UserApproval<'a>

§

impl<'a> Send for UserApproval<'a>

§

impl<'a> Sync for UserApproval<'a>

§

impl<'a> Unpin for UserApproval<'a>

§

impl<'a> UnsafeUnpin for UserApproval<'a>

§

impl<'a> UnwindSafe for UserApproval<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.