Skip to main content

sofie_identity/
lock.rs

1use sofie::core::{Instant, Timestamp};
2use sofie::db::{Db, Uuid};
3use sofie::http::SignIns;
4use sofie::prelude::*;
5
6use crate::account::Account;
7use crate::notice::Notice;
8
9/// An app listens with `#[on]` to tell the owner.
10#[derive(Event)]
11pub struct SignInLocked {
12    pub account: Uuid,
13    pub until: Instant,
14}
15
16/// While a lock holds, every attempt reads as a wrong password, so no answer tells a guess right.
17pub(crate) fn admits(sign_ins: &SignIns, account: Option<&Account>, matches: bool) -> bool {
18    let account = account.map(|account| account.id().uuid());
19    if account.is_some_and(|account| sign_ins.locked(account)) {
20        return false;
21    }
22    if !matches {
23        sign_ins.failed(account);
24    }
25    matches
26}
27
28pub(crate) async fn tell_owner(db: &Db, account: Uuid, until: Timestamp) -> Result<()> {
29    let locked = SignInLocked {
30        account,
31        until: Instant::from(until),
32    };
33    db.commit(&mut Notice::of(locked)?).await
34}