pub struct Eab {
pub kid: Uuid,
pub secret: Vec<u8>,
pub label: Option<String>,
pub profile: Option<String>,
pub status: String,
pub created_at: i64,
}Expand description
An External Account Binding credential (RFC 8555 §7.3.4): a pre-shared
kid + HMAC secret an operator issues out-of-band, presented by a client
at newAccount to prove it was authorized to register.
Reusable: the same key can bind more than one account, until revoked (see
the migration). There is therefore no “used” status, only
active/revoked.
§Methods
create: generate a fresh key and persist it,activefind_by_kid: lookup by kid (the request-time verification path)search: one page of the listing, newest first, plus the unpaged total – the only listing of this table, read byeab list,/ui/eabandGET /api/eabalikerevoke: move to the terminalrevokedstateto_json: admin-facing rendering (never includes the secret)
Fields§
§kid: Uuid§secret: Vec<u8>§label: Option<String>§profile: Option<String>Which ACME endpoint the credential is good for. None means every
profile – the default, for an operator who does not care to scope it.
status: String§created_at: i64Implementations§
Source§impl Eab
impl Eab
Sourcepub async fn create(
label: Option<String>,
profile: Option<String>,
database: &Database,
) -> Result<Eab, Error>
pub async fn create( label: Option<String>, profile: Option<String>, database: &Database, ) -> Result<Eab, Error>
Generates a fresh key (random UUID kid + random 32-byte secret) and
persists it active. Returns the created row so the caller (the
eab create admin command) can print the secret once – this is
the only time it is meant to leave the database in plaintext form.
Sourcepub async fn find_by_kid(
kid: &str,
profile: &str,
database: &Database,
) -> Result<Option<Eab>, Error>
pub async fn find_by_kid( kid: &str, profile: &str, database: &Database, ) -> Result<Option<Eab>, Error>
Looks a credential up for use at profile. A row scoped to another
profile is not returned: to the endpoint asking, it does not exist.
A row with no profile at all matches everywhere.
Sourcepub async fn find_any_by_kid(
kid: &str,
database: &Database,
) -> Result<Option<Eab>, Error>
pub async fn find_any_by_kid( kid: &str, database: &Database, ) -> Result<Option<Eab>, Error>
Looks a credential up by kid regardless of the profile it is scoped to
– the admin CLI’s eab show/eab revoke, where the operator holds the
kid and wants to see it whatever it is bound to. Never the request path,
which must use Eab::find_by_kid.
Sourcepub async fn search(
limit: i64,
offset: i64,
database: &Database,
) -> Result<(Vec<Eab>, i64), Error>
pub async fn search( limit: i64, offset: i64, database: &Database, ) -> Result<(Vec<Eab>, i64), Error>
One page of the listing, plus the total the table holds unpaged.
The only listing of this table: GET /api/eab, /ui/eab and
eab list all read it, which is what stops the three describing one
credential set differently.
Newest first, like Account::search and Order::search. It was
oldest first while the page and the command still read an unpaged
list_all — the reason recorded here was that flipping it would make
the API disagree with them — and that reason expired when both moved
onto this query. What settles the direction now is the mint form:
pages::eab::create_eab re-renders the table out of band so a new
credential appears without a reload, and the only page it can sensibly
render is the first, so the new row has to be on it. kid breaks the
created_at tie for Account::search’s reason — whole-second
timestamps would otherwise let two rows swap between pages, and one of
them would never be seen — and it breaks it DESC, following the
primary key rather than opposing it: a kid is a UUID v7, so an ASC
tiebreak would hand back the oldest of the credentials minted inside
one second, which is exactly the second the mint form re-renders in.
Sourcepub async fn revoke(kid: &str, database: &Database) -> Result<bool, Error>
pub async fn revoke(kid: &str, database: &Database) -> Result<bool, Error>
Moves the key to the terminal-for-new-use revoked state. Existing
accounts bound under it are unaffected (see the migration’s note on
accounts.eab_kid). Idempotent: revoking an already-revoked key still
matches the row and reports true. Returns whether a row existed.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Eab
impl RefUnwindSafe for Eab
impl Send for Eab
impl Sync for Eab
impl Unpin for Eab
impl UnsafeUnpin for Eab
impl UnwindSafe for Eab
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