orca/models/
auth_only.rs
1use crate::model::{self, ActorModel, Transition, TransitionAction, TransitionResult};
2
3use crate::error::Error;
4use crate::run::EventRecord;
5use crate::state::*;
6use kanidm_client::KanidmClient;
7
8use async_trait::async_trait;
9
10use std::time::Duration;
11
12enum State {
13 Unauthenticated,
14 Authenticated,
15}
16
17pub struct ActorAuthOnly {
18 state: State,
19}
20
21impl ActorAuthOnly {
22 pub fn new() -> Self {
23 ActorAuthOnly {
24 state: State::Unauthenticated,
25 }
26 }
27}
28
29#[async_trait]
30impl ActorModel for ActorAuthOnly {
31 async fn transition(
32 &mut self,
33 client: &KanidmClient,
34 person: &Person,
35 ) -> Result<Vec<EventRecord>, Error> {
36 let transition = self.next_transition();
37
38 if let Some(delay) = transition.delay {
39 tokio::time::sleep(delay).await;
40 }
41
42 let (result, event) = match transition.action {
44 TransitionAction::Login => model::login(client, person).await,
45 TransitionAction::Logout => model::logout(client, person).await,
46 _ => Err(Error::InvalidState),
47 }?;
48
49 self.next_state(transition.action, result);
50
51 Ok(event)
52 }
53}
54
55impl ActorAuthOnly {
56 fn next_transition(&mut self) -> Transition {
57 match self.state {
58 State::Unauthenticated => Transition {
59 delay: None,
60 action: TransitionAction::Login,
61 },
62 State::Authenticated => Transition {
63 delay: Some(Duration::from_millis(100)),
64 action: TransitionAction::Logout,
65 },
66 }
67 }
68
69 fn next_state(&mut self, action: TransitionAction, result: TransitionResult) {
70 match (&self.state, action, result) {
71 (State::Unauthenticated, TransitionAction::Login, TransitionResult::Ok) => {
72 self.state = State::Authenticated;
73 }
74 (State::Authenticated, TransitionAction::Logout, TransitionResult::Ok) => {
75 self.state = State::Unauthenticated;
76 }
77 #[allow(clippy::unreachable)]
79 (_, _, TransitionResult::Ok) => {
80 unreachable!();
81 }
82 (_, _, TransitionResult::Error) => {
83 self.state = State::Unauthenticated;
84 }
85 }
86 }
87}