pub struct Challenge {
pub id: Uuid,
pub authz_id: Uuid,
pub typ: String,
pub token: String,
pub status: ChallengeStatus,
pub validated: Option<i64>,
pub error: Option<Value>,
pub created_at: i64,
}Expand description
An ACME challenge (RFC 8555 §8): one proof the client may offer for its authorization’s identifier.
Which types an authorization carries is decided by
ChallengeRegistry::types_for
— UNIQUE(authz_id, type) allows several, one per type. Whether triggering
one performs a real network check or is accepted outright is the registry’s
bypass setting, not this model’s business.
A failed challenge stores the problem document that explains why in error,
which the client reads back from the challenge object.
Fields§
§id: Uuid§authz_id: Uuid§typ: String§token: String§status: ChallengeStatus§validated: Option<i64>§error: Option<Value>The RFC 8555 problem document of a failed validation. None until one
fails.
created_at: i64Implementations§
Source§impl Challenge
impl Challenge
Sourcepub async fn create(
authz_id: Uuid,
typ: &str,
database: &Database,
) -> Result<Challenge, Error>
pub async fn create( authz_id: Uuid, typ: &str, database: &Database, ) -> Result<Challenge, Error>
Creates a new challenge of type typ, with a fresh random token, in the
pending state.
pub async fn find_by_id( id: &str, database: &Database, ) -> Result<Option<Challenge>, Error>
Sourcepub async fn find_by_authz(
authz_id: Uuid,
database: &Database,
) -> Result<Vec<Challenge>, Error>
pub async fn find_by_authz( authz_id: Uuid, database: &Database, ) -> Result<Vec<Challenge>, Error>
Lists an authorization’s challenges (creation order), for the
authorization object’s challenges array.
Sourcepub async fn claim_for_validation(
&mut self,
database: &Database,
) -> Result<bool, Error>
pub async fn claim_for_validation( &mut self, database: &Database, ) -> Result<bool, Error>
Takes this challenge for validation, moving pending to processing.
Returns whether the claim was won. Order::claim_for_finalize’s
primitive, applied one table down and for a sharper reason: the
validator reaches out to an address the client chose, so two triggers
that both pass a status check in memory become two probes of somebody
else’s host. Deciding it in the UPDATE is what makes “exactly one
validation per challenge” a property of the row rather than of how the
handler happens to be scheduled.
A losing caller is not an error: its challenge is already being decided,
and the answer it owes the client is the object as it stands. That
object now says processing, which is exactly what §7.1.6 asks for —
“they transition to the processing state when the client responds to
the challenge” — and §8.2 pairs it with a Retry-After, which
handlers::authz::add_pending_retry_after supplies. A retry request is
explicitly not a state change there, so the loser’s answer is a
conformant one rather than a consolation.
A claim that is never settled (the process dies mid-validation) leaves
the row processing, which is the same trade claim_for_finalize
makes: the authorization’s own expires retires it, and
post_challenge refuses an expired authorization before looking at the
challenge at all.
pub async fn mark_valid(&mut self, database: &Database) -> Result<(), Error>
Sourcepub async fn mark_invalid(
&mut self,
error: Value,
database: &Database,
) -> Result<(), Error>
pub async fn mark_invalid( &mut self, error: Value, database: &Database, ) -> Result<(), Error>
Records a failed validation: moves the challenge to the terminal
invalid state, stores the problem document explaining why, and keeps
self in sync.
validated is deliberately not stamped — RFC 8555 §8 defines it as
the time the challenge was successfully validated.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Challenge
impl RefUnwindSafe for Challenge
impl Send for Challenge
impl Sync for Challenge
impl Unpin for Challenge
impl UnsafeUnpin for Challenge
impl UnwindSafe for Challenge
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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
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