implement icon management and update client app state
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use crate::client::client_auth_api::ClientAuth;
|
||||
use crate::client::opaque::{ServerConnectionLogin, ServerConnectionRegister};
|
||||
use crate::client::repo::ClientRepo;
|
||||
use crate::client::states::{KeyRegister, UserStateCodeLogin, UserStateCodeRegister, UserStateKey};
|
||||
use crate::client::states::{KeyLogin, KeyRegister, UserStateCodeLogin, UserStateCodeRegister, UserStateKey};
|
||||
use crate::shared::models::app::{Icon, IconID};
|
||||
use crate::shared::email::Email;
|
||||
use crate::shared::opaque::UserSecretKey;
|
||||
use crate::shared::user_api::UserAPI;
|
||||
|
||||
struct ClientApp<'a, R, U, C>
|
||||
struct ClientApp<'a, State, R, U, C>
|
||||
where
|
||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
||||
U: UserAPI,
|
||||
@@ -16,11 +17,15 @@ where
|
||||
{
|
||||
auth_api: ClientAuth<'a, R, U>,
|
||||
client_repo: C,
|
||||
new_user: HashMap<Email, UserStateCodeRegister>,
|
||||
user_login: HashMap<Email, UserStateCodeLogin>
|
||||
code_reg: Option<UserStateCodeRegister>,
|
||||
key_login: Option<UserStateKey<KeyLogin>>,
|
||||
code_login: Option<UserStateCodeLogin>,
|
||||
_state: PhantomData<State>
|
||||
}
|
||||
|
||||
impl <'a, R, U, C>ClientApp<'a, R, U, C>
|
||||
|
||||
|
||||
impl <'a,State, R, U, C>ClientApp<'a,State, R, U, C>
|
||||
where
|
||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
||||
U: UserAPI,
|
||||
@@ -30,16 +35,36 @@ where
|
||||
Self {
|
||||
auth_api,
|
||||
client_repo,
|
||||
new_user: HashMap::new(),
|
||||
user_login: HashMap::new()
|
||||
code_reg: None,
|
||||
key_login: None,
|
||||
code_login: None,
|
||||
_state: PhantomData
|
||||
}
|
||||
}
|
||||
fn into_state<NextState>(self) -> ClientApp<'a, NextState, R, U, C> {
|
||||
ClientApp {
|
||||
auth_api: self.auth_api,
|
||||
client_repo: self.client_repo,
|
||||
code_reg: self.code_reg,
|
||||
key_login: self.key_login,
|
||||
code_login: self.code_login,
|
||||
_state: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn new_user(&mut self, email: Email, secret_key: UserSecretKey) -> Result<Vec<Icon>, String> {
|
||||
pub struct NewUserRegisterKey;
|
||||
impl <'a, R, U, C>ClientApp<'a, NewUserRegisterKey, R, U, C>
|
||||
where
|
||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
||||
U: UserAPI,
|
||||
C: ClientRepo,
|
||||
{
|
||||
async fn new_user(mut self, email: Email, secret_key: UserSecretKey) -> Result<ClientApp<'a, NewUserRegisterCode, R, U, C>, String> {
|
||||
let key_register = UserStateKey::<KeyRegister>::new(email.clone(), secret_key.clone());
|
||||
self.client_repo.add_secret_key(email.clone(), secret_key.clone()).await?;
|
||||
let key_login = match key_register.register(&self.auth_api).await.map_err(|e| format!("error: {e:?}")) {
|
||||
Ok(s) => {s}
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
self.client_repo.remove_secret_key(&email).await.expect("couldn't delete");
|
||||
return Err(format!("error registering key {}", e))
|
||||
@@ -47,23 +72,54 @@ where
|
||||
};
|
||||
let key_logged_in = key_login.login(&self.auth_api).await.map_err(|e| format!("error: {e:?}"))?;
|
||||
let code_register = key_logged_in.register_code(&self.auth_api).await?;
|
||||
let icons = code_register.get_icons();
|
||||
self.new_user.insert(email, code_register);
|
||||
Ok(icons)
|
||||
}
|
||||
|
||||
async fn new_user_register_code(&mut self, email: Email, selected_icons: Vec<IconID>) -> Result<Vec<Vec<Icon>>, String> {
|
||||
let code_register = self.new_user.remove(&email).unwrap(); // Todo should be an error
|
||||
let code_login = code_register.register(&self.auth_api,selected_icons).await?;
|
||||
let keypad = code_login.get_keypad().await;
|
||||
self.user_login.insert(email, code_login);
|
||||
Ok(keypad)
|
||||
}
|
||||
|
||||
async fn user_login(&mut self, email: Email, selected_keys: &Vec<usize>) -> Result<(), String> {
|
||||
let mut code_login = self.user_login.remove(&email).unwrap(); // Todo should be an error
|
||||
let code_logged_in = code_login.login(&self.auth_api, &selected_keys).await?;
|
||||
self.client_repo.add_code_logged_in(&email, code_logged_in).await?;
|
||||
Ok(())
|
||||
self.code_reg = Some(code_register);
|
||||
Ok(self.into_state::<NewUserRegisterCode>())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UserKeyLogin;
|
||||
impl <'a, R, U, C>ClientApp<'a, UserKeyLogin, R, U, C>
|
||||
where
|
||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
||||
U: UserAPI,
|
||||
C: ClientRepo,
|
||||
{
|
||||
async fn login(mut self, email: Email, secret_key: UserSecretKey) -> Result<(), String> {
|
||||
let key_login = UserStateKey::<KeyLogin>::new(email, secret_key);
|
||||
self.key_login = Some(key_login);
|
||||
let key_log_in = self.into_state::<UserKeyLogin>();
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NewUserRegisterCode;
|
||||
impl <'a, R, U, C>ClientApp<'a, NewUserRegisterCode, R, U, C>
|
||||
where
|
||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
||||
U: UserAPI,
|
||||
C: ClientRepo,
|
||||
{
|
||||
async fn get_new_user_icons(&self) -> Result<Vec<Icon>, String> {
|
||||
Ok(
|
||||
self.code_reg
|
||||
.clone()
|
||||
.ok_or("no code register".to_string())?
|
||||
.get_icons()
|
||||
)
|
||||
}
|
||||
|
||||
async fn new_user_register_code(mut self, email: Email, selected_icons: Vec<IconID>) -> Result<ClientApp<'a, NewUserRegisterCode, R, U, C>, String> {
|
||||
let code_register = self.code_reg.ok_or("no code register".to_string())?;
|
||||
let code_login = code_register.register(&self.auth_api,selected_icons).await?;
|
||||
todo!()
|
||||
// Ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// async fn user_login(&mut self, email: Email, selected_keys: &Vec<usize>) -> Result<(), String> {
|
||||
// let mut code_login = self.user_login.remove(&email).unwrap(); // Todo should be an error
|
||||
// let code_logged_in = code_login.login(&self.auth_api, &selected_keys).await?;
|
||||
// self.client_repo.add_code_logged_in(&email, code_logged_in).await?;
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Icon, KeyLoggedInSession};
|
||||
use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Icon, KeyLoggedInSession, RegisterCodeData};
|
||||
use crate::shared::email::Email;
|
||||
use crate::shared::opaque::UserSecretKey;
|
||||
use anyhow::Result;
|
||||
@@ -32,12 +32,12 @@ where
|
||||
self.opaque_key_register.register(&auth_data).await.map_err(|e| format!("error: {}", e))
|
||||
}
|
||||
|
||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, data: CodeLoginData) -> Result<(), String> {
|
||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, register_code_data: RegisterCodeData) -> Result<(), String> {
|
||||
let auth_data = OpaqueAuthData::from_code(email.as_str(), passcode);
|
||||
self.opaque_code_register.register(&auth_data).await.map_err(|e| format!("error: {}", e))?;
|
||||
let signed_session = SignedSessionData::new(
|
||||
key_login_session.0.session_id,
|
||||
data,
|
||||
register_code_data,
|
||||
&key_login_session.0.session_key
|
||||
).map_err(|e| format!("error: {e:?}"))?;
|
||||
self.user_api.set_code_login_data(signed_session).await
|
||||
@@ -64,7 +64,8 @@ where
|
||||
async fn get_new_icons(
|
||||
&self,
|
||||
) -> Result<Vec<Icon>, String> {
|
||||
self.user_api.get_new_icons().await
|
||||
let total_props = self.get_policy().await?.keypad_dimension().total_props();
|
||||
self.user_api.get_new_icons(total_props).await
|
||||
}
|
||||
|
||||
async fn get_login_data(
|
||||
|
||||
@@ -3,7 +3,7 @@ use nkode_rs::nkode_core::chacha20prng::Nonce;
|
||||
use nkode_rs::nkode_core::keypad::Keypad;
|
||||
use nkode_rs::nkode_core::nkode_cipher::NKodeCipher;
|
||||
use nkode_rs::from_bytes::FromBytes;
|
||||
use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Icon, IconID, KeyLoggedInSession, ICON_ID_SIZE};
|
||||
use crate::shared::models::app::{AuthAPI, CodeLoggedInSession, CodeLoginData, Icon, IconID, KeyLoggedInSession, RegisterCodeData, ICON_ID_SIZE};
|
||||
use crate::shared::email::Email;
|
||||
use crate::shared::opaque::UserSecretKey;
|
||||
|
||||
@@ -79,10 +79,10 @@ impl UserStateKeyLoggedIn {
|
||||
|
||||
pub async fn login_code(self, api: &dyn AuthAPI) -> Result<UserStateCodeLogin, String> {
|
||||
let login_data = api.get_login_data(&self.key_login).await?;
|
||||
let icons = self.get_icons(api, &login_data.icon_nonce()).await?;
|
||||
let icons = self.get_icons(api, &login_data.icon_nonce).await?;
|
||||
let policy = api.get_policy().await?;
|
||||
let nkode_secret_key = self.user_secret_key.chacha20_secret_key();
|
||||
let cipher = NKodeCipher::from_nonce(policy, &nkode_secret_key, login_data.icon_nonce())?;
|
||||
let cipher = NKodeCipher::from_nonce(policy, &nkode_secret_key, &login_data.icon_nonce)?;
|
||||
Ok(
|
||||
UserStateCodeLogin {
|
||||
email: self.email,
|
||||
@@ -96,6 +96,7 @@ impl UserStateKeyLoggedIn {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UserStateCodeRegister {
|
||||
email: Email,
|
||||
user_secret_key: UserSecretKey,
|
||||
@@ -121,8 +122,13 @@ impl UserStateCodeRegister {
|
||||
cipher_nonce,
|
||||
icon_nonce: self.icon_nonce,
|
||||
keypad,
|
||||
email: self.email.clone()
|
||||
};
|
||||
api.register_code(&self.email, &ciphered_nkode.passcode, &self.key_login, data.clone()).await?;
|
||||
let register_data = RegisterCodeData {
|
||||
code_login_data: data.clone(),
|
||||
icons: self.icons.clone(),
|
||||
};
|
||||
api.register_code(&self.email, &ciphered_nkode.passcode, &self.key_login, register_data).await?;
|
||||
Ok(UserStateCodeLogin {
|
||||
mask: data.mask,
|
||||
email: self.email,
|
||||
|
||||
@@ -85,3 +85,4 @@ where
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,18 +2,22 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use nkode_rs::nkode_core::keypad::Keypad;
|
||||
use rand::Rng;
|
||||
use rand::rngs::ThreadRng;
|
||||
use tokio::sync::Mutex;
|
||||
use uuid::Uuid;
|
||||
use crate::server::repository::user_repo::UserRepo;
|
||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, Icon, KeyLoggedInSession};
|
||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, Icon, IconID, KeyLoggedInSession, RegisterCodeData};
|
||||
use crate::shared::email::Email;
|
||||
use crate::shared::signed_session_data::SignedSessionData;
|
||||
use crate::shared::user_api::UserAPI;
|
||||
use crate::shared::user_api::{IconPoolAPI, UserAPI};
|
||||
|
||||
pub struct InMemoryUserDB {
|
||||
key_session: Arc<Mutex<HashMap<Uuid, KeyLoggedInSession>>>,
|
||||
code_session: Arc<Mutex<HashMap<Uuid, CodeLoggedInSession>>>,
|
||||
code_data: Arc<Mutex<HashMap<Email, CodeLoginData>>>,
|
||||
code_data_store: Arc<Mutex<HashMap<Email, CodeLoginData>>>,
|
||||
owned_icons: Arc<Mutex<HashMap<IconID, Icon>>>,
|
||||
icon_pool: Arc<Mutex<Vec<Icon>>>
|
||||
}
|
||||
|
||||
impl InMemoryUserDB {
|
||||
@@ -21,7 +25,9 @@ impl InMemoryUserDB {
|
||||
Self {
|
||||
key_session: Arc::new(Mutex::new(HashMap::new())),
|
||||
code_session: Arc::new(Mutex::new(HashMap::new())),
|
||||
code_data: Arc::new(Mutex::new(HashMap::new())),
|
||||
code_data_store: Arc::new(Mutex::new(HashMap::new())),
|
||||
owned_icons: Arc::new(Mutex::new(HashMap::new())),
|
||||
icon_pool: Arc::new(Mutex::new(Vec::new())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,22 +55,22 @@ impl UserRepo for InMemoryUserDB {
|
||||
}
|
||||
|
||||
async fn set_key_session(&self, session: KeyLoggedInSession) -> Result<(), String> {
|
||||
self.key_session.lock().await.insert(session.0.session_id, session);
|
||||
self.key_session.lock().await.insert(session.0.session_id, session).ok_or("couldn't set key session".to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn set_code_session(&self, session: CodeLoggedInSession) -> Result<(), String> {
|
||||
self.code_session.lock().await.insert(session.0.session_id, session);
|
||||
self.code_session.lock().await.insert(session.0.session_id, session).ok_or("couldn't set code session".to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn set_code_login_data(&self, email: Email, data: CodeLoginData) -> Result<(), String> {
|
||||
self.code_data.lock().await.insert(email, data);
|
||||
self.code_data_store.lock().await.insert(email, data).ok_or("couldn't set code login data")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_code_login_data(&self, email: &Email) -> Result<CodeLoginData, String> {
|
||||
self.code_data.lock().await
|
||||
self.code_data_store.lock().await
|
||||
.get(email)
|
||||
.cloned()
|
||||
.ok_or_else(|| "code login data not found for email".to_string())
|
||||
@@ -73,23 +79,87 @@ impl UserRepo for InMemoryUserDB {
|
||||
|
||||
#[async_trait]
|
||||
impl UserAPI for InMemoryUserDB {
|
||||
async fn get_new_icons(&self) -> Result<Vec<Icon>, String> {
|
||||
todo!()
|
||||
async fn get_new_icons(&self, n: usize) -> Result<Vec<Icon>, String> {
|
||||
let mut pool = self.icon_pool.lock().await;
|
||||
if n > pool.len() {
|
||||
return Err(format!(
|
||||
"not enough icons in pool: requested {}, have {}",
|
||||
n,
|
||||
pool.len()
|
||||
));
|
||||
}
|
||||
let mut rng: ThreadRng = rand::thread_rng();
|
||||
let mut out = Vec::with_capacity(n);
|
||||
for _ in 0..n {
|
||||
let idx = rng.gen_range(0..pool.len());
|
||||
out.push(pool.swap_remove(idx));
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
async fn get_login_data(&self, session: SignedSessionData<Email>) -> Result<CodeLoginData, String> {
|
||||
todo!()
|
||||
let key_session = self.get_key_session(&session.session_id).await?;
|
||||
if key_session.0.email != session.data {
|
||||
return Err("email does not match session email".to_string());
|
||||
}
|
||||
session.verify(&key_session.0.session_key).map_err(|e| format!("session error: {e:?}"))?;
|
||||
self.get_code_login_data(&session.data).await
|
||||
}
|
||||
|
||||
async fn is_code_registered(&self, session: SignedSessionData<Email>) -> Result<bool, String> {
|
||||
todo!()
|
||||
let _ = self.get_login_data(session).await?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
async fn set_code_login_data(&self, session: SignedSessionData<CodeLoginData>) -> Result<(), String> {
|
||||
todo!()
|
||||
async fn set_code_login_data(&self, session: SignedSessionData<RegisterCodeData>) -> Result<(), String> {
|
||||
let key_session = self.get_key_session(&session.session_id).await?;
|
||||
session.verify(&key_session.0.session_key).map_err(|e| format!("session error: {e:?}"))?;
|
||||
self.code_data_store.lock().await.insert(session.data.code_login_data.email.clone(), session.data.code_login_data).ok_or("couldn't set code data".to_string())?;
|
||||
let mut owned_icons = self.owned_icons.lock().await;
|
||||
for icon in session.data.icons {
|
||||
let icon_id = icon.id().clone();
|
||||
owned_icons.insert(icon_id.clone(), icon).ok_or(format!("error inserting icon into owned icons {}", icon_id))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_keypad(&self, keypad: SignedSessionData<Keypad>) -> Result<(), String> {
|
||||
todo!()
|
||||
async fn update_keypad(&self, session: SignedSessionData<Keypad>) -> Result<(), String> {
|
||||
let key_session = self.get_key_session(&session.session_id).await?;
|
||||
session.verify(&key_session.0.session_key).map_err(|e| format!("session error: {e:?}"))?;
|
||||
let email = key_session.0.email;
|
||||
let mut code_data_store = self.code_data_store.lock().await;
|
||||
let mut code_data = code_data_store.remove(&email).ok_or("user doesn't have code data".to_string())?;
|
||||
code_data.keypad = session.data;
|
||||
code_data_store.insert(email, code_data).ok_or("couldn't update keypad")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_icons(&self, icon_ids: &[IconID]) -> Result<Vec<Icon>, String> {
|
||||
let owned_icons = self.owned_icons.lock().await;
|
||||
let mut user_icons = Vec::<Icon>::with_capacity(icon_ids.len());
|
||||
for id in icon_ids {
|
||||
let icon = owned_icons.get(id).cloned().ok_or(format!("icon: {} dne", id))?;
|
||||
user_icons.push(icon);
|
||||
}
|
||||
Ok(user_icons)
|
||||
}
|
||||
|
||||
async fn set_icons(&self, session: SignedSessionData<Vec<Icon>>) -> Result<(), String> {
|
||||
let key_session = self.get_key_session(&session.session_id).await?;
|
||||
session.verify(&key_session.0.session_key).map_err(|e| format!("session error: {e:?}"))?;
|
||||
let mut owned_icons = self.owned_icons.lock().await;
|
||||
for icon in session.data {
|
||||
let icon_id = icon.id().clone();
|
||||
owned_icons.insert(icon_id.clone(), icon).ok_or(format!("error inserting icon into owned icons {}", icon_id))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl IconPoolAPI for InMemoryUserDB {
|
||||
async fn add_icons(&self, icons: Vec<Icon>) -> Result<(), String> {
|
||||
self.icon_pool.lock().await.extend(icons);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::fmt;
|
||||
use async_trait::async_trait;
|
||||
use nkode_rs::nkode_core::chacha20prng::Nonce; use nkode_rs::nkode_core::keypad::Keypad;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -22,9 +23,18 @@ pub struct KeyLoggedInSession(pub(crate) LoggedInSession);
|
||||
pub struct CodeLoggedInSession(pub(crate) LoggedInSession);
|
||||
|
||||
pub const ICON_ID_SIZE: usize = 32;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq,Hash, Serialize, Deserialize)]
|
||||
pub struct IconID([u8; 32]);
|
||||
|
||||
impl fmt::Display for IconID {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for b in &self.0 {
|
||||
write!(f, "{:02x}", b)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromBytes<ICON_ID_SIZE> for IconID {
|
||||
fn from_array(arr: [u8; ICON_ID_SIZE]) -> Self {
|
||||
Self(arr)
|
||||
@@ -45,22 +55,25 @@ impl Icon {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Getters, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CodeLoginData {
|
||||
#[get = "pub"]
|
||||
pub(crate) email: Email,
|
||||
pub(crate) mask: Vec<u64>,
|
||||
#[get = "pub"]
|
||||
pub(crate) cipher_nonce: Nonce,
|
||||
#[get = "pub"]
|
||||
pub(crate) icon_nonce: Nonce,
|
||||
#[get = "pub"]
|
||||
pub(crate) keypad: Keypad,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RegisterCodeData {
|
||||
pub(crate) code_login_data: CodeLoginData,
|
||||
pub(crate) icons: Vec<Icon>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AuthAPI {
|
||||
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String>;
|
||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, data: CodeLoginData) -> Result<(), String>;
|
||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, register_data: RegisterCodeData) -> Result<(), String>;
|
||||
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoggedInSession, String>;
|
||||
async fn login_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoggedInSession, keypad: Keypad) -> Result<CodeLoggedInSession, String>;
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ impl<T> SignedSessionData<T>
|
||||
where
|
||||
T: Serialize + DeserializeOwned,
|
||||
{
|
||||
/// Create a signed envelope around (session_id, issued/expires, data).
|
||||
pub fn new(
|
||||
session_id: Uuid,
|
||||
data: T,
|
||||
@@ -57,7 +56,6 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
/// Verify signature + time bounds.
|
||||
pub fn verify(&self, session_key: &OpaqueSessionKey) -> Result<(), SignedSessionError> {
|
||||
let expected = Self::compute_signature(
|
||||
self.session_id,
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
use async_trait::async_trait;
|
||||
use nkode_rs::nkode_core::keypad::Keypad;
|
||||
use crate::shared::email::Email;
|
||||
use crate::shared::models::app::{CodeLoginData, Icon};
|
||||
use crate::shared::models::app::{CodeLoginData, Icon, IconID, RegisterCodeData};
|
||||
use crate::shared::signed_session_data::SignedSessionData;
|
||||
|
||||
#[async_trait]
|
||||
pub trait UserAPI: Sync + Send {
|
||||
// TODO: this should have a session
|
||||
async fn get_new_icons(&self) -> Result<Vec<Icon>, String>;
|
||||
async fn get_new_icons(&self, n: usize) -> Result<Vec<Icon>, String>;
|
||||
async fn get_login_data(&self, session: SignedSessionData<Email>) -> Result<CodeLoginData, String>;
|
||||
async fn is_code_registered(&self, session: SignedSessionData<Email>) -> Result<bool, String>;
|
||||
async fn set_code_login_data(&self, session: SignedSessionData<CodeLoginData>) -> Result<(), String>;
|
||||
async fn update_keypad(&self, keypad: SignedSessionData<Keypad>) -> Result<(), String>;
|
||||
async fn set_code_login_data(&self, session: SignedSessionData<RegisterCodeData>) -> Result<(), String>;
|
||||
async fn update_keypad(&self, session: SignedSessionData<Keypad>) -> Result<(), String>;
|
||||
async fn get_icons(&self, icon_ids: &[IconID]) -> Result<Vec<Icon>, String>;
|
||||
async fn set_icons(&self, session: SignedSessionData<Vec<Icon>>) -> Result<(), String>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait IconPoolAPI: Sync + Send {
|
||||
async fn add_icons(&self, icons: Vec<Icon>) -> Result<(), String>;
|
||||
}
|
||||
Reference in New Issue
Block a user