implement client app
This commit is contained in:
@@ -1,88 +1,54 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
use nkode_rs::nkode_core::keypad::Keypad;
|
use nkode_rs::nkode_core::keypad::Keypad;
|
||||||
use crate::models::app::{CodeLoginData, CodeLoginSession, Icon, IconID, KeyLoginSession, ICON_ID_SIZE};
|
use crate::models::app::{CodeLoginData, CodeLoginSession, Icon, IconID, KeyLoginSession, ServerAPI, ICON_ID_SIZE};
|
||||||
use crate::models::email::Email;
|
use crate::models::email::Email;
|
||||||
use crate::models::opaque::UserSecretKey;
|
use crate::models::opaque::UserSecretKey;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use nkode_rs::nkode_core::nkode_cipher::NKodeCipher;
|
use nkode_rs::nkode_core::nkode_cipher::NKodeCipher;
|
||||||
use nkode_rs::nkode_core::policy::NKodePolicy;
|
|
||||||
use nkode_rs::from_bytes::FromBytes;
|
use nkode_rs::from_bytes::FromBytes;
|
||||||
use nkode_rs::nkode_core::chacha20prng::Nonce;
|
use nkode_rs::nkode_core::chacha20prng::Nonce;
|
||||||
|
use crate::repository::client_app::repos::ClientRepo;
|
||||||
|
|
||||||
pub trait ServerAPI {
|
pub struct Login;
|
||||||
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String>;
|
pub struct Register;
|
||||||
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoginSession, data: &CodeLoginData) -> Result<(), String>;
|
|
||||||
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoginSession, String>;
|
|
||||||
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoginSession, String>;
|
|
||||||
async fn get_new_icons(&self, key_login_session: &KeyLoginSession) -> Result<Vec<Icon>, String>;
|
|
||||||
async fn get_login_data(&self, key_login_session: &KeyLoginSession) -> Result<CodeLoginData, String>;
|
|
||||||
async fn is_code_registered(&self, key_login_session: &KeyLoginSession) -> Result<bool, String>;
|
|
||||||
async fn get_policy(&self) -> Result<NKodePolicy, String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RegisterKey;
|
|
||||||
|
|
||||||
impl RegisterKey {
|
pub struct ClientAppKey<State, S: ServerAPI, R: ClientRepo> {
|
||||||
pub async fn register<S: ServerAPI>(api: S, email: Email, user_secret_key: &UserSecretKey) -> Result<KeyLogin<S>, String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct KeyLogin<S: ServerAPI> {
|
|
||||||
api: S,
|
api: S,
|
||||||
|
repo: R,
|
||||||
email: Email,
|
email: Email,
|
||||||
user_secret_key: UserSecretKey
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <S: ServerAPI>KeyLogin<S> {
|
|
||||||
pub async fn login_register_code(self) -> RegisterCode<S> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn login_with_data(self, data: CodeLoginData) -> CodeLogin<S> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn login_without_data(self) -> CodeLogin<S> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RegisterCode<S: ServerAPI> {
|
|
||||||
api: S,
|
|
||||||
user_secret_key: UserSecretKey,
|
user_secret_key: UserSecretKey,
|
||||||
key_login_session: KeyLoginSession,
|
_state: PhantomData<State>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: ServerAPI>RegisterCode<S> {
|
impl <S: ServerAPI, R: ClientRepo> ClientAppKey<Register,S, R> {
|
||||||
pub async fn get_new_icons(&self) -> Result<Vec<Icon>, String> {
|
pub async fn register(self) -> Result<ClientAppKey<Login, S, R>, String> {
|
||||||
todo!()
|
self.repo.set_secret_key(&self.email, &self.user_secret_key).await?;
|
||||||
}
|
self.api.register_key(&self.email, &self.user_secret_key).await?;
|
||||||
|
Ok(ClientAppKey {
|
||||||
pub async fn register(self, email: Email, passcode: &[u64]) -> Result<CodeLoginData, String> {
|
api: self.api,
|
||||||
todo!()
|
repo: self.repo,
|
||||||
|
email: self.email,
|
||||||
|
user_secret_key: self.user_secret_key,
|
||||||
|
_state: PhantomData::<Login>,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CodeLogin<S: ServerAPI> {
|
impl <S: ServerAPI, R: ClientRepo> ClientAppKey<Login,S, R> {
|
||||||
api: S,
|
pub async fn login(self) -> Result<ClientAppKeyLoggedIn<S,R>,String> {
|
||||||
}
|
let key_login = self.api.login_key(&self.email, &self.user_secret_key).await?;
|
||||||
|
Ok(ClientAppKeyLoggedIn{
|
||||||
impl <S: ServerAPI>CodeLogin<S> {
|
repo: self.repo,
|
||||||
pub async fn login(self, email: Email, passcode: &[u64]) -> Result<CodeLoginSession, String> {
|
api: self.api,
|
||||||
todo!()
|
email: self.email,
|
||||||
|
user_secret_key: self.user_secret_key,
|
||||||
|
key_login
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ClientRepo {
|
pub struct ClientAppKeyLoggedIn<S: ServerAPI, R: ClientRepo> {
|
||||||
async fn get_secret_key(&self) -> Result<UserSecretKey, String>;
|
|
||||||
async fn set_secret_key(&self, email: &Email,user_secret_key: &UserSecretKey) -> Result<(),String>;
|
|
||||||
async fn get_login_data(&self) -> Result<CodeLoginData, String>;
|
|
||||||
async fn set_login_data(&self, data: CodeLoginData) -> Result<(), String>;
|
|
||||||
async fn set_email(&self, email: &Email) -> Result<(), String>;
|
|
||||||
async fn get_email(&self) -> Result<Email, String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ClientAppKey<S: ServerAPI, R: ClientRepo> {
|
|
||||||
repo: R,
|
repo: R,
|
||||||
api: S,
|
api: S,
|
||||||
email: Email,
|
email: Email,
|
||||||
@@ -90,20 +56,7 @@ pub struct ClientAppKey<S: ServerAPI, R: ClientRepo> {
|
|||||||
key_login: KeyLoginSession,
|
key_login: KeyLoginSession,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S: ServerAPI, R: ClientRepo> ClientAppKey<S, R> {
|
impl <S: ServerAPI, R: ClientRepo> ClientAppKeyLoggedIn<S, R> {
|
||||||
pub async fn new_register(email: Email, user_secret_key: UserSecretKey, repo: R, api: S) -> Result<Self, String> {
|
|
||||||
repo.set_secret_key(&email, &user_secret_key).await?;
|
|
||||||
api.register_key(&email, &user_secret_key).await?;
|
|
||||||
let key_login = api.login_key(&email, &user_secret_key).await?;
|
|
||||||
Ok(Self {
|
|
||||||
repo,
|
|
||||||
api,
|
|
||||||
email,
|
|
||||||
user_secret_key,
|
|
||||||
key_login,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn register_code(self) -> Result<ClientAppCodeRegister<S>, String> {
|
pub async fn register_code(self) -> Result<ClientAppCodeRegister<S>, String> {
|
||||||
let icon_nonce = Nonce::new();
|
let icon_nonce = Nonce::new();
|
||||||
let icons = self.get_icons(&icon_nonce).await?;
|
let icons = self.get_icons(&icon_nonce).await?;
|
||||||
@@ -132,7 +85,21 @@ impl <S: ServerAPI, R: ClientRepo> ClientAppKey<S, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login_code(self) -> Result<ClientAppCodeLogin<S>, String> {
|
pub async fn login_code(self) -> Result<ClientAppCodeLogin<S>, String> {
|
||||||
todo!()
|
let login_data = self.api.get_login_data(&self.key_login).await?;
|
||||||
|
let icons = self.get_icons(&login_data.icon_nonce()).await?;
|
||||||
|
let policy = self.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())?;
|
||||||
|
Ok(
|
||||||
|
ClientAppCodeLogin{
|
||||||
|
api: self.api,
|
||||||
|
email: self.email,
|
||||||
|
mask: login_data.mask,
|
||||||
|
icons,
|
||||||
|
keypad: login_data.keypad,
|
||||||
|
cipher,
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,18 +125,17 @@ impl <S: ServerAPI>ClientAppCodeRegister<S> {
|
|||||||
.collect();
|
.collect();
|
||||||
let ciphered_nkode = cipher.encipher(&passcode_idx).unwrap();
|
let ciphered_nkode = cipher.encipher(&passcode_idx).unwrap();
|
||||||
let data = CodeLoginData{
|
let data = CodeLoginData{
|
||||||
mask: ciphered_nkode.mask.clone(),
|
mask: ciphered_nkode.mask,
|
||||||
icons: self.icons.clone(),
|
|
||||||
cipher_nonce,
|
cipher_nonce,
|
||||||
icon_nonce: self.icon_nonce.clone(),
|
icon_nonce: self.icon_nonce,
|
||||||
keypad: keypad.clone(),
|
keypad,
|
||||||
};
|
};
|
||||||
self.api.register_code(&self.email, &ciphered_nkode.passcode, &self.key_login, &data).await?;
|
self.api.register_code(&self.email, &ciphered_nkode.passcode, &self.key_login, &data).await?;
|
||||||
Ok(ClientAppCodeLogin{
|
Ok(ClientAppCodeLogin{
|
||||||
api: self.api,
|
api: self.api,
|
||||||
mask: ciphered_nkode.mask,
|
mask: data.mask,
|
||||||
email: self.email,
|
email: self.email,
|
||||||
keypad,
|
keypad: data.keypad,
|
||||||
cipher,
|
cipher,
|
||||||
icons: self.icons
|
icons: self.icons
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use getset::Getters;
|
use getset::Getters;
|
||||||
use nkode_rs::from_bytes::FromBytes;
|
use nkode_rs::from_bytes::FromBytes;
|
||||||
|
use nkode_rs::nkode_core::policy::NKodePolicy;
|
||||||
use crate::models::email::Email;
|
use crate::models::email::Email;
|
||||||
use crate::models::opaque::OpaqueSessionKey;
|
use crate::models::opaque::{OpaqueSessionKey, UserSecretKey};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct LoginSession {
|
struct LoginSession {
|
||||||
@@ -44,8 +45,8 @@ impl Icon {
|
|||||||
pub struct CodeLoginData {
|
pub struct CodeLoginData {
|
||||||
#[get = "pub"]
|
#[get = "pub"]
|
||||||
pub(crate) mask: Vec<u64>,
|
pub(crate) mask: Vec<u64>,
|
||||||
#[get = "pub"]
|
// #[get = "pub"]
|
||||||
pub(crate) icons: Vec<Icon>,
|
// pub(crate) icons: Vec<Icon>,
|
||||||
#[get = "pub"]
|
#[get = "pub"]
|
||||||
pub(crate) cipher_nonce: Nonce,
|
pub(crate) cipher_nonce: Nonce,
|
||||||
#[get = "pub"]
|
#[get = "pub"]
|
||||||
@@ -53,3 +54,14 @@ pub struct CodeLoginData {
|
|||||||
#[get = "pub"]
|
#[get = "pub"]
|
||||||
pub(crate) keypad: Keypad,
|
pub(crate) keypad: Keypad,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ServerAPI {
|
||||||
|
async fn register_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<(), String>;
|
||||||
|
async fn register_code(&self, email: &Email, passcode: &[u64], key_login_session: &KeyLoginSession, data: &CodeLoginData) -> Result<(), String>;
|
||||||
|
async fn login_key(&self, email: &Email, secret_key: &UserSecretKey) -> Result<KeyLoginSession, String>;
|
||||||
|
async fn login_code(&self, email: &Email, passcode: &[u64]) -> Result<CodeLoginSession, String>;
|
||||||
|
async fn get_new_icons(&self, key_login_session: &KeyLoginSession) -> Result<Vec<Icon>, String>;
|
||||||
|
async fn get_login_data(&self, key_login_session: &KeyLoginSession) -> Result<CodeLoginData, String>;
|
||||||
|
async fn is_code_registered(&self, key_login_session: &KeyLoginSession) -> Result<bool, String>;
|
||||||
|
async fn get_policy(&self) -> Result<NKodePolicy, String>;
|
||||||
|
}
|
||||||
1
src/repository/client_app/mod.rs
Normal file
1
src/repository/client_app/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod repos;
|
||||||
12
src/repository/client_app/repos.rs
Normal file
12
src/repository/client_app/repos.rs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
use crate::models::app::CodeLoginData;
|
||||||
|
use crate::models::email::Email;
|
||||||
|
use crate::models::opaque::UserSecretKey;
|
||||||
|
|
||||||
|
pub trait ClientRepo {
|
||||||
|
async fn get_secret_key(&self) -> anyhow::Result<UserSecretKey, String>;
|
||||||
|
async fn set_secret_key(&self, email: &Email,user_secret_key: &UserSecretKey) -> anyhow::Result<(),String>;
|
||||||
|
async fn get_login_data(&self) -> anyhow::Result<CodeLoginData, String>;
|
||||||
|
async fn set_login_data(&self, data: CodeLoginData) -> anyhow::Result<(), String>;
|
||||||
|
async fn set_email(&self, email: &Email) -> anyhow::Result<(), String>;
|
||||||
|
async fn get_email(&self) -> anyhow::Result<Email, String>;
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
pub mod opaque;
|
pub mod opaque;
|
||||||
|
pub(crate) mod client_app;
|
||||||
|
|||||||
Reference in New Issue
Block a user