junobuild_auth/state/
heap.rs1use crate::openid::types::provider::{OpenIdCertificate, OpenIdProvider};
2use crate::state::types::config::AuthenticationConfig;
3use crate::state::types::state::Salt;
4use crate::state::types::state::{AuthenticationHeapState, OpenIdCachedCertificate, OpenIdState};
5use crate::strategies::AuthHeapStrategy;
6use std::collections::hash_map::Entry;
7
8pub fn get_config(auth_heap: &impl AuthHeapStrategy) -> Option<AuthenticationConfig> {
13 auth_heap
14 .with_auth_state(|authentication| authentication.as_ref().map(|auth| auth.config.clone()))
15}
16
17pub fn insert_config(auth_heap: &impl AuthHeapStrategy, config: &AuthenticationConfig) {
18 auth_heap.with_auth_state_mut(|authentication| insert_config_impl(config, authentication))
19}
20
21fn insert_config_impl(config: &AuthenticationConfig, state: &mut Option<AuthenticationHeapState>) {
22 match state {
23 None => {
24 *state = Some(AuthenticationHeapState {
25 config: config.clone(),
26 salt: None,
27 openid: None,
28 })
29 }
30 Some(state) => state.config = config.clone(),
31 }
32}
33
34pub fn get_salt(auth_heap: &impl AuthHeapStrategy) -> Option<Salt> {
39 auth_heap.with_auth_state(|authentication| authentication.as_ref().and_then(|auth| auth.salt))
40}
41
42pub fn insert_salt(auth_heap: &impl AuthHeapStrategy, salt: &Salt) {
43 auth_heap.with_auth_state_mut(|authentication| insert_salt_impl(salt, authentication))
44}
45
46fn insert_salt_impl(salt: &Salt, state: &mut Option<AuthenticationHeapState>) {
47 match state {
48 None => {
49 *state = Some(AuthenticationHeapState {
50 config: AuthenticationConfig::default(),
51 salt: Some(*salt),
52 openid: None,
53 })
54 }
55 Some(state) => state.salt = Some(*salt),
56 }
57}
58
59pub fn get_openid_state(auth_heap: &impl AuthHeapStrategy) -> Option<OpenIdState> {
64 auth_heap.with_auth_state(|authentication| {
65 authentication.as_ref().and_then(|auth| auth.openid.clone())
66 })
67}
68
69pub fn get_cached_certificate(
70 provider: &OpenIdProvider,
71 auth_heap: &impl AuthHeapStrategy,
72) -> Option<OpenIdCachedCertificate> {
73 auth_heap
74 .with_auth_state(|authentication| get_cached_certificate_impl(provider, authentication))
75}
76
77pub fn cache_certificate(
78 provider: &OpenIdProvider,
79 certificate: &OpenIdCertificate,
80 auth_heap: &impl AuthHeapStrategy,
81) -> Result<(), String> {
82 auth_heap.with_auth_state_mut(|authentication| {
83 cache_certificate_impl(provider, certificate, authentication)
84 })
85}
86
87pub fn record_fetch_attempt(
88 provider: &OpenIdProvider,
89 reset_streak: bool,
90 auth_heap: &impl AuthHeapStrategy,
91) {
92 auth_heap.with_auth_state_mut(|authentication| {
93 record_fetch_attempt_impl(provider, reset_streak, authentication)
94 })
95}
96
97fn get_cached_certificate_impl(
98 provider: &OpenIdProvider,
99 state: &Option<AuthenticationHeapState>,
100) -> Option<OpenIdCachedCertificate> {
101 state
102 .as_ref()
103 .and_then(|auth| auth.openid.as_ref())
104 .and_then(|openid| openid.certificates.get(provider))
105 .cloned()
106}
107
108fn record_fetch_attempt_impl(
109 provider: &OpenIdProvider,
110 reset_streak: bool,
111 state: &mut Option<AuthenticationHeapState>,
112) {
113 let authentication = state.get_or_insert_with(AuthenticationHeapState::default);
114 let openid_state = authentication
115 .openid
116 .get_or_insert_with(OpenIdState::default);
117
118 openid_state
119 .certificates
120 .entry(provider.clone())
121 .and_modify(|cached_certificate| cached_certificate.record_attempt(reset_streak))
122 .or_insert_with(OpenIdCachedCertificate::init);
123}
124
125fn cache_certificate_impl(
126 provider: &OpenIdProvider,
127 certificate: &OpenIdCertificate,
128 state: &mut Option<AuthenticationHeapState>,
129) -> Result<(), String> {
130 let authentication = state.get_or_insert_with(AuthenticationHeapState::default);
131 let openid_state = authentication
132 .openid
133 .get_or_insert_with(OpenIdState::default);
134
135 match openid_state.certificates.entry(provider.clone()) {
136 Entry::Occupied(mut occ) => {
137 occ.get_mut().update_certificate(certificate);
138 Ok(())
139 }
140 Entry::Vacant(_) => Err("Cannot cache certificate: fetch attempt was not recorded".into()),
141 }
142}