pub struct LoginService<R, G>{ /* private fields */ }Expand description
Stateless service implementing constant‑time, enumeration‑resistant authentication logic.
It always performs:
- Account lookup by user identifier.
- Credential verification against either the real account UUID or a fixed dummy UUID when the account is absent.
This equalises timing characteristics between “user not found” and “wrong password” cases.
Type Params:
R- Role type implementingAccessHierarchyG- Group type
Implementations§
Source§impl<R, G> LoginService<R, G>
impl<R, G> LoginService<R, G>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new stateless LoginService.
The instance holds no mutable state; it is cheap to clone or recreate.
Sourcepub async fn authenticate<CredVeri, AccRepo, C>(
&self,
credentials: Credentials<String>,
registered_claims: RegisteredClaims,
credentials_verifier: Arc<CredVeri>,
account_repository: Arc<AccRepo>,
codec: Arc<C>,
) -> LoginResultwhere
CredVeri: CredentialsVerifier<Uuid>,
AccRepo: AccountRepository<R, G>,
C: Codec<Payload = JwtClaims<Account<R, G>>>,
pub async fn authenticate<CredVeri, AccRepo, C>(
&self,
credentials: Credentials<String>,
registered_claims: RegisteredClaims,
credentials_verifier: Arc<CredVeri>,
account_repository: Arc<AccRepo>,
codec: Arc<C>,
) -> LoginResultwhere
CredVeri: CredentialsVerifier<Uuid>,
AccRepo: AccountRepository<R, G>,
C: Codec<Payload = JwtClaims<Account<R, G>>>,
Authenticates a user in a timing‑safe, enumeration‑resistant fashion.
Steps:
- Query account repository by user identifier.
- Always invoke credential verification using either the real account UUID or a fixed dummy UUID when the user is absent / lookup failed.
- Combine (user_exists AND password_matches) with constant‑time bit logic.
- On success, encode a JWT with the supplied registered claims.
Returns:
LoginResult::Successwith a JWT string on success.LoginResult::InvalidCredentialsfor any auth failure that should not leak detail.LoginResult::InternalErrorfor infrastructural issues (these should be logged).
Security: Avoids early returns that would create observable timing differences between “user not found” and “wrong password”.
Trait Implementations§
Auto Trait Implementations§
impl<R, G> Freeze for LoginService<R, G>
impl<R, G> RefUnwindSafe for LoginService<R, G>where
R: RefUnwindSafe,
G: RefUnwindSafe,
impl<R, G> Send for LoginService<R, G>
impl<R, G> Sync for LoginService<R, G>
impl<R, G> Unpin for LoginService<R, G>
impl<R, G> UnsafeUnpin for LoginService<R, G>
impl<R, G> UnwindSafe for LoginService<R, G>where
R: UnwindSafe,
G: UnwindSafe,
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
Mutably borrows from an owned value. Read more
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>
Converts
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>
Converts
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