pub struct MagicLinkUseCases { /* private fields */ }Implementations§
Source§impl MagicLinkUseCases
impl MagicLinkUseCases
pub fn new(repo: Arc<dyn MagicLinkRepository>) -> Self
Sourcepub async fn issue(
&self,
subject_user_id: Uuid,
scope_kind: MagicLinkScopeKind,
scope_id: Uuid,
issued_by: Uuid,
expires_in_seconds: i64,
) -> Result<IssuedMagicLinkDto, AppError>
pub async fn issue( &self, subject_user_id: Uuid, scope_kind: MagicLinkScopeKind, scope_id: Uuid, issued_by: Uuid, expires_in_seconds: i64, ) -> Result<IssuedMagicLinkDto, AppError>
Issue a new MagicLink. Caller MUST have already authorised the request (syndic / superadmin role check happens at the handler level).
Sourcepub async fn validate_and_consume(
&self,
clear_token: &str,
) -> Result<MagicLink, AppError>
pub async fn validate_and_consume( &self, clear_token: &str, ) -> Result<MagicLink, AppError>
Validate a clear token and atomically consume it.
Possible errors (all map to HTTP 403 by design — see CRITICAL.md #4 and the AppError mapping in error.rs):
AppError::MagicLinkInvalid— token not found (forged / unknown).AppError::MagicLinkExpired— TTL elapsed.AppError::MagicLinkAlreadyConsumed— replay attempt on used token.
Sourcepub async fn peek(&self, clear_token: &str) -> Result<MagicLink, AppError>
pub async fn peek(&self, clear_token: &str) -> Result<MagicLink, AppError>
Resolve a token WITHOUT consuming it — for scopes whose workflow spans
several round-trips after the first GET /c/{token} (#835 @edge).
ContractorReport is the first such scope: a prestataire opens the
link (which consumes it via Self::validate_and_consume as an audit
marker of “first redemption”), then edits a draft and submits later —
possibly offline, possibly the next day. Gating that later write on
consumed_at would make the very first view burn the only chance to
ever submit, which is incompatible with the offline requirement this
scope must keep (cf. system B being absorbed, which only ever checked
TTL). So peek checks hash lookup + expiry only, and deliberately
ignores consumed_at. Scope cloisonnement is enforced separately by
Self::ensure_scope at the call site — a token’s scope_kind is
fixed at issuance and never reinterpreted.
Sourcepub fn ensure_scope(
link: &MagicLink,
expected: MagicLinkScopeKind,
) -> Result<(), AppError>
pub fn ensure_scope( link: &MagicLink, expected: MagicLinkScopeKind, ) -> Result<(), AppError>
Enforce that a resolved link matches the scope the caller expects.
Returns the same uniform MagicLinkInvalid as an unknown token — a
link issued for Quote must not distinguishably fail as “wrong scope”
(anti-enumeration, same rationale as validate_and_consume’s uniform
“unknown token” error), and must not open a ContractorReport (#835
@security — élargir un scope est le moyen le plus simple de
transformer un lien ciblé en passe-partout).
Auto Trait Implementations§
impl !RefUnwindSafe for MagicLinkUseCases
impl !UnwindSafe for MagicLinkUseCases
impl Freeze for MagicLinkUseCases
impl Send for MagicLinkUseCases
impl Sync for MagicLinkUseCases
impl Unpin for MagicLinkUseCases
impl UnsafeUnpin for MagicLinkUseCases
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Fake for T
impl<T> Fake for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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