junobuild_auth/state/
heap.rs1use crate::openid::types::provider::{OpenIdCertificate, OpenIdProvider};
2use crate::state::types::automation::AutomationConfig;
3use crate::state::types::config::AuthenticationConfig;
4use crate::state::types::state::Salt;
5use crate::state::types::state::{AuthenticationHeapState, OpenIdCachedCertificate, OpenIdState};
6use crate::strategies::AuthHeapStrategy;
7use std::collections::hash_map::Entry;
8
9pub fn get_config(auth_heap: &impl AuthHeapStrategy) -> Option<AuthenticationConfig> {
14 auth_heap
15 .with_auth_state(|authentication| authentication.as_ref().map(|auth| auth.config.clone()))
16}
17
18pub fn insert_config(auth_heap: &impl AuthHeapStrategy, config: &AuthenticationConfig) {
19 auth_heap.with_auth_state_mut(|authentication| insert_config_impl(config, authentication))
20}
21
22fn insert_config_impl(config: &AuthenticationConfig, state: &mut Option<AuthenticationHeapState>) {
23 match state {
24 None => {
25 *state = Some(AuthenticationHeapState {
26 config: config.clone(),
27 automation: None,
28 salt: None,
29 openid: None,
30 })
31 }
32 Some(state) => state.config = config.clone(),
33 }
34}
35
36pub fn get_automation(auth_heap: &impl AuthHeapStrategy) -> Option<AutomationConfig> {
41 auth_heap.with_auth_state(|authentication| {
42 authentication
43 .as_ref()
44 .and_then(|auth| auth.automation.clone())
45 })
46}
47
48pub fn insert_automation(auth_heap: &impl AuthHeapStrategy, automation: &AutomationConfig) {
49 auth_heap
50 .with_auth_state_mut(|authentication| insert_automation_impl(automation, authentication))
51}
52
53fn insert_automation_impl(
54 automation: &AutomationConfig,
55 state: &mut Option<AuthenticationHeapState>,
56) {
57 match state {
58 None => {
59 *state = Some(AuthenticationHeapState {
60 config: AuthenticationConfig::default(),
61 automation: Some(automation.clone()),
62 salt: None,
63 openid: None,
64 })
65 }
66 Some(state) => state.automation = Some(automation.clone()),
67 }
68}
69
70pub fn get_salt(auth_heap: &impl AuthHeapStrategy) -> Option<Salt> {
75 auth_heap.with_auth_state(|authentication| authentication.as_ref().and_then(|auth| auth.salt))
76}
77
78pub fn insert_salt(auth_heap: &impl AuthHeapStrategy, salt: &Salt) {
79 auth_heap.with_auth_state_mut(|authentication| insert_salt_impl(salt, authentication))
80}
81
82fn insert_salt_impl(salt: &Salt, state: &mut Option<AuthenticationHeapState>) {
83 match state {
84 None => {
85 *state = Some(AuthenticationHeapState {
86 config: AuthenticationConfig::default(),
87 automation: None,
88 salt: Some(*salt),
89 openid: None,
90 })
91 }
92 Some(state) => state.salt = Some(*salt),
93 }
94}
95
96pub fn get_openid_state(auth_heap: &impl AuthHeapStrategy) -> Option<OpenIdState> {
101 auth_heap.with_auth_state(|authentication| {
102 authentication.as_ref().and_then(|auth| auth.openid.clone())
103 })
104}
105
106pub fn get_cached_certificate(
107 provider: &OpenIdProvider,
108 auth_heap: &impl AuthHeapStrategy,
109) -> Option<OpenIdCachedCertificate> {
110 auth_heap
111 .with_auth_state(|authentication| get_cached_certificate_impl(provider, authentication))
112}
113
114pub fn cache_certificate(
115 provider: &OpenIdProvider,
116 certificate: &OpenIdCertificate,
117 auth_heap: &impl AuthHeapStrategy,
118) -> Result<(), String> {
119 auth_heap.with_auth_state_mut(|authentication| {
120 cache_certificate_impl(provider, certificate, authentication)
121 })
122}
123
124pub fn record_fetch_attempt(
125 provider: &OpenIdProvider,
126 reset_streak: bool,
127 auth_heap: &impl AuthHeapStrategy,
128) {
129 auth_heap.with_auth_state_mut(|authentication| {
130 record_fetch_attempt_impl(provider, reset_streak, authentication)
131 })
132}
133
134fn get_cached_certificate_impl(
135 provider: &OpenIdProvider,
136 state: &Option<AuthenticationHeapState>,
137) -> Option<OpenIdCachedCertificate> {
138 state
139 .as_ref()
140 .and_then(|auth| auth.openid.as_ref())
141 .and_then(|openid| openid.certificates.get(provider))
142 .cloned()
143}
144
145fn record_fetch_attempt_impl(
146 provider: &OpenIdProvider,
147 reset_streak: bool,
148 state: &mut Option<AuthenticationHeapState>,
149) {
150 let authentication = state.get_or_insert_with(AuthenticationHeapState::default);
151 let openid_state = authentication
152 .openid
153 .get_or_insert_with(OpenIdState::default);
154
155 openid_state
156 .certificates
157 .entry(provider.clone())
158 .and_modify(|cached_certificate| cached_certificate.record_attempt(reset_streak))
159 .or_insert_with(OpenIdCachedCertificate::init);
160}
161
162fn cache_certificate_impl(
163 provider: &OpenIdProvider,
164 certificate: &OpenIdCertificate,
165 state: &mut Option<AuthenticationHeapState>,
166) -> Result<(), String> {
167 let authentication = state.get_or_insert_with(AuthenticationHeapState::default);
168 let openid_state = authentication
169 .openid
170 .get_or_insert_with(OpenIdState::default);
171
172 match openid_state.certificates.entry(provider.clone()) {
173 Entry::Occupied(mut occ) => {
174 occ.get_mut().update_certificate(certificate);
175 Ok(())
176 }
177 Entry::Vacant(_) => Err("Cannot cache certificate: fetch attempt was not recorded".into()),
178 }
179}