testing client app
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use crate::client::client_auth_api::ClientAuth;
|
use crate::client::client_auth_api::ClientAuth;
|
||||||
use crate::client::opaque::{ServerConnectionLogin, ServerConnectionRegister};
|
use crate::client::opaque::{ServerConnectionLogin, ServerConnectionRegister};
|
||||||
@@ -9,14 +8,15 @@ use crate::shared::email::Email;
|
|||||||
use crate::shared::opaque::UserSecretKey;
|
use crate::shared::opaque::UserSecretKey;
|
||||||
use crate::shared::user_api::UserAPI;
|
use crate::shared::user_api::UserAPI;
|
||||||
|
|
||||||
struct ClientApp<'a, State, R, U, C>
|
pub struct ClientApp<'a,'b ,State, K,C, U, R>
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
U: UserAPI,
|
U: UserAPI,
|
||||||
C: ClientRepo
|
R: ClientRepo
|
||||||
{
|
{
|
||||||
auth_api: ClientAuth<'a, R, U>,
|
auth_api: ClientAuth<'a,'b ,K,C, U>,
|
||||||
client_repo: C,
|
client_repo: R,
|
||||||
code_reg: Option<UserStateCodeRegister>,
|
code_reg: Option<UserStateCodeRegister>,
|
||||||
key_login: Option<UserStateKey<KeyLogin>>,
|
key_login: Option<UserStateKey<KeyLogin>>,
|
||||||
code_login: Option<UserStateCodeLogin>,
|
code_login: Option<UserStateCodeLogin>,
|
||||||
@@ -25,13 +25,14 @@ where
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl <'a,State, R, U, C>ClientApp<'a,State, R, U, C>
|
impl <'a,'b ,State, K,C, U, R>ClientApp<'a,'b ,State, K,C, U, R>
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
U: UserAPI,
|
U: UserAPI,
|
||||||
C: ClientRepo,
|
R: ClientRepo,
|
||||||
{
|
{
|
||||||
pub fn new(auth_api: ClientAuth<'a, R, U>, client_repo: C) -> Self {
|
pub fn new(auth_api: ClientAuth<'a,'b , K,C, U>, client_repo: R) -> Self {
|
||||||
Self {
|
Self {
|
||||||
auth_api,
|
auth_api,
|
||||||
client_repo,
|
client_repo,
|
||||||
@@ -41,7 +42,8 @@ where
|
|||||||
_state: PhantomData
|
_state: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn into_state<NextState>(self) -> ClientApp<'a, NextState, R, U, C> {
|
|
||||||
|
fn into_state<NextState>(self) -> ClientApp<'a,'b, NextState, K,C, U, R> {
|
||||||
ClientApp {
|
ClientApp {
|
||||||
auth_api: self.auth_api,
|
auth_api: self.auth_api,
|
||||||
client_repo: self.client_repo,
|
client_repo: self.client_repo,
|
||||||
@@ -54,13 +56,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct NewUserRegisterKey;
|
pub struct NewUserRegisterKey;
|
||||||
impl <'a, R, U, C>ClientApp<'a, NewUserRegisterKey, R, U, C>
|
impl <'a,'b, K, C, U, R> ClientApp<'a,'b, NewUserRegisterKey, K,C, U, R>
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
U: UserAPI,
|
U: UserAPI,
|
||||||
C: ClientRepo,
|
R: ClientRepo,
|
||||||
{
|
{
|
||||||
async fn new_user(mut self, email: Email, secret_key: UserSecretKey) -> Result<ClientApp<'a, NewUserRegisterCode, R, U, C>, String> {
|
pub async fn new_user(mut self, email: Email, secret_key: UserSecretKey) -> Result<ClientApp<'a,'b, NewUserRegisterCode, K,C, U, R>, String> {
|
||||||
let key_register = UserStateKey::<KeyRegister>::new(email.clone(), secret_key.clone());
|
let key_register = UserStateKey::<KeyRegister>::new(email.clone(), secret_key.clone());
|
||||||
self.client_repo.add_secret_key(email.clone(), secret_key.clone()).await?;
|
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:?}")) {
|
let key_login = match key_register.register(&self.auth_api).await.map_err(|e| format!("error: {e:?}")) {
|
||||||
@@ -71,35 +74,22 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let key_logged_in = key_login.login(&self.auth_api).await.map_err(|e| format!("error: {e:?}"))?;
|
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 code_register = key_logged_in.to_register_code(&self.auth_api).await?;
|
||||||
self.code_reg = Some(code_register);
|
self.code_reg = Some(code_register);
|
||||||
Ok(self.into_state::<NewUserRegisterCode>())
|
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;
|
pub struct NewUserRegisterCode;
|
||||||
impl <'a, R, U, C>ClientApp<'a, NewUserRegisterCode, R, U, C>
|
|
||||||
|
impl <'a,'b, K, C, U, R> ClientApp<'a,'b, NewUserRegisterCode, K,C, U, R>
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
U: UserAPI,
|
U: UserAPI,
|
||||||
C: ClientRepo,
|
R: ClientRepo,
|
||||||
{
|
{
|
||||||
async fn get_new_user_icons(&self) -> Result<Vec<Icon>, String> {
|
pub async fn get_new_user_icons(&self) -> Result<Vec<Icon>, String> {
|
||||||
Ok(
|
Ok(
|
||||||
self.code_reg
|
self.code_reg
|
||||||
.clone()
|
.clone()
|
||||||
@@ -108,18 +98,49 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn new_user_register_code(mut self, email: Email, selected_icons: Vec<IconID>) -> Result<ClientApp<'a, NewUserRegisterCode, R, U, C>, String> {
|
pub async fn new_user_register_code(mut self, selected_icons: Vec<IconID>) -> Result<ClientApp<'a,'b, UserCodeLogin, K,C, U, R>, String> {
|
||||||
let code_register = self.code_reg.ok_or("no code register".to_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?;
|
self.code_reg = None;
|
||||||
todo!()
|
self.code_login = Some(code_register.clone().register(&self.auth_api,selected_icons).await?);
|
||||||
// Ok()
|
Ok(self.into_state::<UserCodeLogin>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// async fn user_login(&mut self, email: Email, selected_keys: &Vec<usize>) -> Result<(), String> {
|
pub struct UserKeyLogin;
|
||||||
// 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?;
|
impl <'a,'b, K, C, U, R> ClientApp<'a,'b, UserKeyLogin, K,C, U, R>
|
||||||
// self.client_repo.add_code_logged_in(&email, code_logged_in).await?;
|
where
|
||||||
// Ok(())
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
// }
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
U: UserAPI,
|
||||||
|
R: ClientRepo,
|
||||||
|
{
|
||||||
|
pub async fn login(mut self, email: Email, secret_key: UserSecretKey) -> Result<ClientApp<'a,'b, UserCodeLogin,K,C, U, R>, String> {
|
||||||
|
self.code_login = Some(
|
||||||
|
UserStateKey::<KeyLogin>::new(email, secret_key)
|
||||||
|
.login(&self.auth_api).await?
|
||||||
|
.to_code_login(&self.auth_api).await?
|
||||||
|
);
|
||||||
|
Ok(self.into_state::<UserCodeLogin>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UserCodeLogin;
|
||||||
|
impl <'a,'b, K, C, U, R> ClientApp<'a,'b, UserCodeLogin, K,C, U, R>
|
||||||
|
where
|
||||||
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
U: UserAPI,
|
||||||
|
R: ClientRepo,
|
||||||
|
{
|
||||||
|
pub async fn get_keypad(&self) -> Result<Vec<Vec<Icon>>, String> {
|
||||||
|
let code_login = self.code_login.clone().ok_or("no code login")?;
|
||||||
|
Ok(code_login.get_keypad().await)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn login(self, key_selection: Vec<usize>) -> Result<(), String> {
|
||||||
|
let code_login = self.code_login.unwrap().login(&self.auth_api, &key_selection).await?;
|
||||||
|
self.client_repo.add_code_logged_in(code_login.0.email.clone(), code_login).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,22 +9,42 @@ use crate::client::opaque::{OpaqueAuthData, OpaqueAuth, ServerConnectionLogin, S
|
|||||||
use crate::shared::signed_session_data::SignedSessionData;
|
use crate::shared::signed_session_data::SignedSessionData;
|
||||||
use crate::shared::user_api::UserAPI;
|
use crate::shared::user_api::UserAPI;
|
||||||
|
|
||||||
pub struct ClientAuth<'a, R, U>
|
pub struct ClientAuth<'a,'b, K,C, U>
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
U: UserAPI
|
U: UserAPI
|
||||||
{
|
{
|
||||||
opaque_key_register: OpaqueAuth<'a, R>,
|
opaque_key_register: OpaqueAuth<'a, K>,
|
||||||
opaque_key_login: OpaqueAuth<'a, R>,
|
opaque_key_login: OpaqueAuth<'a, K>,
|
||||||
opaque_code_register: OpaqueAuth<'a, R>,
|
opaque_code_register: OpaqueAuth<'b, C>,
|
||||||
opaque_code_login: OpaqueAuth<'a, R>,
|
opaque_code_login: OpaqueAuth<'b, C>,
|
||||||
user_api: U
|
user_api: U
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
impl<'a,'b, K,C, U> ClientAuth<'a,'b, K,C, U>
|
||||||
impl<'a, R, U> AuthAPI for ClientAuth<'a, R, U>
|
|
||||||
where
|
where
|
||||||
R: ServerConnectionRegister + ServerConnectionLogin,
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
U: UserAPI,
|
||||||
|
{
|
||||||
|
pub fn new(key_connection: &'a K, code_connection: &'b C, user_api: U) -> Self {
|
||||||
|
Self{
|
||||||
|
opaque_key_register: OpaqueAuth::new(key_connection),
|
||||||
|
opaque_key_login: OpaqueAuth::new(key_connection),
|
||||||
|
opaque_code_login: OpaqueAuth::new(code_connection),
|
||||||
|
opaque_code_register: OpaqueAuth::new(code_connection),
|
||||||
|
user_api
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<'a,'b, K,C, U> AuthAPI for ClientAuth<'a,'b, K,C, U>
|
||||||
|
where
|
||||||
|
K: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
|
C: ServerConnectionRegister + ServerConnectionLogin,
|
||||||
U: UserAPI,
|
U: UserAPI,
|
||||||
{
|
{
|
||||||
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String> {
|
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String> {
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ pub mod client_auth_api;
|
|||||||
pub mod opaque;
|
pub mod opaque;
|
||||||
pub mod states;
|
pub mod states;
|
||||||
pub mod app;
|
pub mod app;
|
||||||
mod repo;
|
pub mod repo;
|
||||||
@@ -87,8 +87,8 @@ pub trait ServerConnectionLogin: Send + Sync {
|
|||||||
pub struct OpaqueAuth<'a, S>(&'a S);
|
pub struct OpaqueAuth<'a, S>(&'a S);
|
||||||
|
|
||||||
impl<'a, S> OpaqueAuth<'a, S> {
|
impl<'a, S> OpaqueAuth<'a, S> {
|
||||||
pub fn new(server: &'a S) -> Self {
|
pub fn new(server_connection: &'a S) -> Self {
|
||||||
Self(server)
|
Self(server_connection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,63 @@ use async_trait::async_trait;
|
|||||||
use crate::shared::email::Email;
|
use crate::shared::email::Email;
|
||||||
use crate::shared::models::app::CodeLoggedInSession;
|
use crate::shared::models::app::CodeLoggedInSession;
|
||||||
use crate::shared::opaque::UserSecretKey;
|
use crate::shared::opaque::UserSecretKey;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait ClientRepo {
|
pub trait ClientRepo {
|
||||||
async fn add_secret_key(&self, email: Email, user_secret_key: UserSecretKey) -> Result<(), String>;
|
async fn add_secret_key(&self, email: Email, user_secret_key: UserSecretKey) -> Result<(), String>;
|
||||||
async fn remove_secret_key(&self, email: &Email) -> Result<(), String>;
|
async fn remove_secret_key(&self, email: &Email) -> Result<(), String>;
|
||||||
async fn add_code_logged_in(&self, email: &Email, login_session: CodeLoggedInSession) -> Result<(), String>;
|
async fn add_code_logged_in(&self, email: Email, login_session: CodeLoggedInSession) -> Result<(), String>;
|
||||||
|
async fn get_code_logged_in(&self, email: &Email) -> Result<CodeLoggedInSession, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: Implement in memory repo
|
#[derive(Debug, Default)]
|
||||||
|
pub struct InMemoryClientRepo {
|
||||||
|
secret_keys: RwLock<HashMap<Email, UserSecretKey>>,
|
||||||
|
code_logged_in: RwLock<HashMap<Email, CodeLoggedInSession>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InMemoryClientRepo {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience if you want to share it across services.
|
||||||
|
pub fn shared() -> Arc<Self> {
|
||||||
|
Arc::new(Self::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl ClientRepo for InMemoryClientRepo {
|
||||||
|
async fn add_secret_key(&self, email: Email, user_secret_key: UserSecretKey) -> Result<(), String> {
|
||||||
|
let mut map = self.secret_keys.write().await;
|
||||||
|
map.insert(email, user_secret_key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn remove_secret_key(&self, email: &Email) -> Result<(), String> {
|
||||||
|
let mut map = self.secret_keys.write().await;
|
||||||
|
map.remove(email);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn add_code_logged_in(&self, email: Email, login_session: CodeLoggedInSession) -> Result<(), String> {
|
||||||
|
let mut map = self.code_logged_in.write().await;
|
||||||
|
map.insert(email, login_session);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_code_logged_in(&self, email: &Email) -> Result<CodeLoggedInSession, String> {
|
||||||
|
let map = self.code_logged_in.read().await;
|
||||||
|
map.get(email)
|
||||||
|
.cloned()
|
||||||
|
.ok_or_else(|| "code_logged_in session not found".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Implement flutter-storage
|
// TODO: Implement flutter-storage
|
||||||
// https://chatgpt.com/c/69441737-c990-8333-9737-7ac75232da1d
|
// https://chatgpt.com/c/69441737-c990-8333-9737-7ac75232da1d
|
||||||
@@ -53,7 +53,7 @@ pub struct UserStateKeyLoggedIn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UserStateKeyLoggedIn {
|
impl UserStateKeyLoggedIn {
|
||||||
pub async fn register_code(self, api: &dyn AuthAPI) -> Result<UserStateCodeRegister, String> {
|
pub async fn to_register_code(self, api: &dyn AuthAPI) -> Result<UserStateCodeRegister, String> {
|
||||||
let icon_nonce = Nonce::new();
|
let icon_nonce = Nonce::new();
|
||||||
let icons = self.get_icons(api, &icon_nonce).await?;
|
let icons = self.get_icons(api, &icon_nonce).await?;
|
||||||
Ok(UserStateCodeRegister {
|
Ok(UserStateCodeRegister {
|
||||||
@@ -77,7 +77,7 @@ impl UserStateKeyLoggedIn {
|
|||||||
Ok(icons)
|
Ok(icons)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login_code(self, api: &dyn AuthAPI) -> Result<UserStateCodeLogin, String> {
|
pub async fn to_code_login(self, api: &dyn AuthAPI) -> Result<UserStateCodeLogin, String> {
|
||||||
let login_data = api.get_login_data(&self.key_login).await?;
|
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 policy = api.get_policy().await?;
|
||||||
@@ -144,6 +144,7 @@ impl UserStateCodeRegister {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct UserStateCodeLogin {
|
pub struct UserStateCodeLogin {
|
||||||
email: Email,
|
email: Email,
|
||||||
mask: Vec<u64>,
|
mask: Vec<u64>,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use rand::rngs::OsRng;
|
|||||||
|
|
||||||
const USER_KEY_SIZE: usize = 16;
|
const USER_KEY_SIZE: usize = 16;
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct UserSecretKey(Zeroizing<[u8; USER_KEY_SIZE]>);
|
pub struct UserSecretKey(Zeroizing<[u8; USER_KEY_SIZE]>);
|
||||||
|
|
||||||
impl UserSecretKey {
|
impl UserSecretKey {
|
||||||
|
|||||||
49
tests/in_memory_client_app_test.rs
Normal file
49
tests/in_memory_client_app_test.rs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
use opaque_ke::argon2::password_hash::rand_core::OsRng;
|
||||||
|
use nkode_protocol::client::app::{ClientApp, NewUserRegisterKey};
|
||||||
|
use nkode_protocol::client::client_auth_api::ClientAuth;
|
||||||
|
use nkode_protocol::client::repo::InMemoryClientRepo;
|
||||||
|
use nkode_protocol::server::app::ServerApp;
|
||||||
|
use nkode_protocol::server::repository::in_memory::in_memory_opaque_db::InMemoryOpaqueDB;
|
||||||
|
use nkode_protocol::server::repository::in_memory::in_memory_opaque_session::InMemoryOpaqueSession;
|
||||||
|
use nkode_protocol::server::repository::in_memory::in_memory_transport::{InMemoryCodeServer, InMemoryKeyServer, InMemoryServerTransport};
|
||||||
|
use nkode_protocol::server::repository::in_memory::in_memory_user_db::InMemoryUserDB;
|
||||||
|
use nkode_protocol::shared::email::Email;
|
||||||
|
use nkode_protocol::shared::models::app::IconID;
|
||||||
|
use nkode_protocol::shared::opaque::{NKodeServerSetup, UserSecretKey};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn in_memory_client_app() {
|
||||||
|
|
||||||
|
let mut rng = OsRng;
|
||||||
|
let server_setup = NKodeServerSetup::new(&mut rng);
|
||||||
|
let server = ServerApp::new(
|
||||||
|
server_setup,
|
||||||
|
InMemoryOpaqueDB::new(),
|
||||||
|
InMemoryOpaqueSession::new(),
|
||||||
|
InMemoryUserDB::new()
|
||||||
|
);
|
||||||
|
let key_transport: InMemoryKeyServer = InMemoryServerTransport::new(&server);
|
||||||
|
let code_transport: InMemoryCodeServer = InMemoryServerTransport::new(&server);
|
||||||
|
let user_db = InMemoryUserDB::new();
|
||||||
|
let client_auth = ClientAuth::new(&key_transport, &code_transport, user_db);
|
||||||
|
let client_repo = InMemoryClientRepo::new();
|
||||||
|
let client_app_new_user: ClientApp<
|
||||||
|
'_,
|
||||||
|
'_,
|
||||||
|
NewUserRegisterKey,
|
||||||
|
InMemoryServerTransport<'_, _>,
|
||||||
|
InMemoryServerTransport<'_, _>,
|
||||||
|
_,
|
||||||
|
_
|
||||||
|
> = ClientApp::new(client_auth, client_repo);
|
||||||
|
let user_email = Email::new("a@b.com").unwrap();
|
||||||
|
let user_secret_key = UserSecretKey::new();
|
||||||
|
let client_app_register_code = client_app_new_user.new_user(user_email, user_secret_key).await.unwrap();
|
||||||
|
let _: Vec<IconID> = client_app_register_code
|
||||||
|
.get_new_user_icons().await.unwrap()
|
||||||
|
.iter()
|
||||||
|
.map(
|
||||||
|
|el| el.id().clone()
|
||||||
|
).collect();
|
||||||
|
// let client_app_user_login = client_app_register_code.new_user_register_code(icons[0..4].to_vec()).await.unwrap();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user