refactor mutibility
This commit is contained in:
@@ -23,7 +23,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reg_start<K: CredKind>(
|
pub async fn reg_start<K: CredKind>(
|
||||||
&mut self,
|
&self,
|
||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
request: RegistrationRequest<NKodeCipherSuite>,
|
request: RegistrationRequest<NKodeCipherSuite>,
|
||||||
) -> Result<OpaqueRegisterSession, String> {
|
) -> Result<OpaqueRegisterSession, String> {
|
||||||
@@ -42,7 +42,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reg_finish<K: CredKind>(
|
pub async fn reg_finish<K: CredKind>(
|
||||||
&mut self,
|
&self,
|
||||||
session_id: &Uuid,
|
session_id: &Uuid,
|
||||||
password_file: PasswordFile,
|
password_file: PasswordFile,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
@@ -51,7 +51,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
.map_err(|e| format!("get reg session: {e}"))?;
|
.map_err(|e| format!("get reg session: {e}"))?;
|
||||||
K::prereq_for_register(&self.opaque_db, sess.identifier.as_slice()).await
|
K::prereq_for_register(&self.opaque_db, sess.identifier.as_slice()).await
|
||||||
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
.map_err(|e| format!("registration prereq failed: {e:?}"))?;
|
||||||
K::set_password_file(&mut self.opaque_db, sess.identifier.as_slice(), password_file).await
|
K::set_password_file(&self.opaque_db, sess.identifier.as_slice(), password_file).await
|
||||||
.map_err(|e| format!("repo write: {e:?}"))?;
|
.map_err(|e| format!("repo write: {e:?}"))?;
|
||||||
self.opaque_sess
|
self.opaque_sess
|
||||||
.clear_reg_session(session_id).await
|
.clear_reg_session(session_id).await
|
||||||
@@ -59,7 +59,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login_start<K: CredKind>(
|
pub async fn login_start<K: CredKind>(
|
||||||
&mut self,
|
&self,
|
||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
request: CredentialRequest<NKodeCipherSuite>,
|
request: CredentialRequest<NKodeCipherSuite>,
|
||||||
) -> Result<OpaqueLoginSession, String> {
|
) -> Result<OpaqueLoginSession, String> {
|
||||||
@@ -85,7 +85,7 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login_finish(
|
pub async fn login_finish(
|
||||||
&mut self,
|
&self,
|
||||||
session_id: &Uuid,
|
session_id: &Uuid,
|
||||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||||
) -> Result<LoggedInSession, String> {
|
) -> Result<LoggedInSession, String> {
|
||||||
@@ -108,39 +108,39 @@ impl<R: OpaqueDatabaseRepo, S: OpaqueSessionRepo, U: UserRepo> ServerApp<R, S, U
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn key_login_finish(
|
pub async fn key_login_finish(
|
||||||
&mut self,
|
&self,
|
||||||
session_id: &Uuid,
|
session_id: &Uuid,
|
||||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||||
) -> Result<KeyLoggedInSession, String> {
|
) -> Result<KeyLoggedInSession, String> {
|
||||||
let session = KeyLoggedInSession(self.login_finish(session_id, finalize).await?);
|
let session = KeyLoggedInSession(self.login_finish(session_id, finalize).await?);
|
||||||
self.user_db.set_key_session(session.clone())?;
|
self.user_db.set_key_session(session.clone()).await?;
|
||||||
Ok(session)
|
Ok(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn code_login_finish(
|
pub async fn code_login_finish(
|
||||||
&mut self,
|
&self,
|
||||||
session_id: &Uuid,
|
session_id: &Uuid,
|
||||||
finalize: CredentialFinalization<NKodeCipherSuite>,
|
finalize: CredentialFinalization<NKodeCipherSuite>,
|
||||||
) -> Result<CodeLoggedInSession, String> {
|
) -> Result<CodeLoggedInSession, String> {
|
||||||
let session = CodeLoggedInSession(self.login_finish(session_id, finalize).await?);
|
let session = CodeLoggedInSession(self.login_finish(session_id, finalize).await?);
|
||||||
self.user_db.set_code_session(session.clone())?;
|
self.user_db.set_code_session(session.clone()).await?;
|
||||||
Ok(session)
|
Ok(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_key_session(&mut self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
pub async fn get_key_session(&self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
||||||
self.user_db.get_key_session(session_id)
|
self.user_db.get_key_session(session_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_code_session(&mut self, session_id: &Uuid) -> Result<CodeLoggedInSession, String> {
|
pub async fn get_code_session(&self, session_id: &Uuid) -> Result<CodeLoggedInSession, String> {
|
||||||
self.user_db.get_code_session(session_id)
|
self.user_db.get_code_session(session_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_code_login_data(&mut self, email: &Email) -> Result<CodeLoginData, String> {
|
pub async fn get_code_login_data(&self, email: &Email) -> Result<CodeLoginData, String> {
|
||||||
self.user_db.get_code_login_data(email)
|
self.user_db.get_code_login_data(email).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_code_login_data(&mut self, email: Email, data: CodeLoginData) -> Result<(), String> {
|
pub async fn set_code_login_data(&self, email: Email, data: CodeLoginData) -> Result<(), String> {
|
||||||
self.user_db.set_code_login_data(email, data)
|
self.user_db.set_code_login_data(email, data).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ impl CredKind for Key {
|
|||||||
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||||
repo.get_key_passcode_file(id).await
|
repo.get_key_passcode_file(id).await
|
||||||
}
|
}
|
||||||
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||||
repo.new_key(id, pf).await
|
repo.new_key(id, pf).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ impl CredKind for Code {
|
|||||||
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||||
repo.get_code_passcode_file(id).await
|
repo.get_code_passcode_file(id).await
|
||||||
}
|
}
|
||||||
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError> {
|
||||||
repo.new_code(id, pf).await
|
repo.new_code(id, pf).await
|
||||||
}
|
}
|
||||||
async fn prereq_for_register<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<(), AuthRepoError> {
|
async fn prereq_for_register<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<(), AuthRepoError> {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub struct LoginCache {
|
|||||||
pub trait CredKind {
|
pub trait CredKind {
|
||||||
async fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool;
|
async fn has<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> bool;
|
||||||
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
async fn get_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||||
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &mut R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError>;
|
async fn set_password_file<R: OpaqueDatabaseRepo>(repo: &R, id: &[u8], pf: PasswordFile) -> Result<(), AuthRepoError>;
|
||||||
async fn prereq_for_register<R: OpaqueDatabaseRepo>(_repo: &R, _id: &[u8]) -> Result<(), AuthRepoError> {
|
async fn prereq_for_register<R: OpaqueDatabaseRepo>(_repo: &R, _id: &[u8]) -> Result<(), AuthRepoError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use tokio::sync::Mutex;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest};
|
use opaque_ke::{CredentialFinalization, CredentialRequest, RegistrationRequest};
|
||||||
use crate::shared::models::opaque::{NKodeCipherSuite, NKodeServerSetup, OpaqueLoginSession, OpaqueRegisterSession, PasswordFile};
|
use crate::shared::models::opaque::{NKodeCipherSuite, NKodeServerSetup, OpaqueLoginSession, OpaqueRegisterSession, PasswordFile};
|
||||||
@@ -14,23 +12,20 @@ use crate::server::repository::in_memory::in_memory_opaque_session::InMemoryOpaq
|
|||||||
use crate::server::repository::in_memory::in_memory_user_db::InMemoryUserDB;
|
use crate::server::repository::in_memory::in_memory_user_db::InMemoryUserDB;
|
||||||
use crate::shared::models::app::LoggedInSession;
|
use crate::shared::models::app::LoggedInSession;
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct InMemoryServer<K: CredKind> {
|
pub struct InMemoryServer<K: CredKind> {
|
||||||
auth_db: Arc<Mutex<ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>>>,
|
auth_db: ServerApp<InMemoryOpaqueDB, InMemoryOpaqueSession, InMemoryUserDB>,
|
||||||
_kind: PhantomData<K>,
|
_kind: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: CredKind> InMemoryServer<K> {
|
impl<K: CredKind> InMemoryServer<K> {
|
||||||
pub fn new(server_setup: NKodeServerSetup) -> Self {
|
pub fn new(server_setup: NKodeServerSetup) -> Self {
|
||||||
Self {
|
Self {
|
||||||
auth_db: Arc::new(Mutex::new(
|
auth_db: ServerApp::new(
|
||||||
ServerApp::new(
|
server_setup,
|
||||||
server_setup,
|
InMemoryOpaqueDB::new(),
|
||||||
InMemoryOpaqueDB::new(),
|
InMemoryOpaqueSession::new(),
|
||||||
InMemoryOpaqueSession::new(),
|
InMemoryUserDB::new()
|
||||||
InMemoryUserDB::new()
|
),
|
||||||
)
|
|
||||||
)),
|
|
||||||
_kind: PhantomData,
|
_kind: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +46,7 @@ where
|
|||||||
) -> Result<OpaqueRegisterSession, ClientAuthError> {
|
) -> Result<OpaqueRegisterSession, ClientAuthError> {
|
||||||
// Server API takes ownership; client trait gives us a reference.
|
// Server API takes ownership; client trait gives us a reference.
|
||||||
// opaque-ke request types are typically Clone; if not, you'll need to adjust signatures.
|
// opaque-ke request types are typically Clone; if not, you'll need to adjust signatures.
|
||||||
self.auth_db.lock().await
|
self.auth_db
|
||||||
.reg_start::<K>(identifier, message.clone())
|
.reg_start::<K>(identifier, message.clone())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(e))
|
.map_err(|e| ClientAuthError::Transport(e))
|
||||||
@@ -62,8 +57,7 @@ where
|
|||||||
session_id: &Uuid,
|
session_id: &Uuid,
|
||||||
password_file: PasswordFile,
|
password_file: PasswordFile,
|
||||||
) -> Result<(), ClientAuthError> {
|
) -> Result<(), ClientAuthError> {
|
||||||
self.auth_db.lock().await
|
self.auth_db.reg_finish::<K>(session_id, password_file)
|
||||||
.reg_finish::<K>(session_id, password_file)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(e))
|
.map_err(|e| ClientAuthError::Transport(e))
|
||||||
}
|
}
|
||||||
@@ -79,7 +73,7 @@ where
|
|||||||
identifier: &[u8],
|
identifier: &[u8],
|
||||||
request: &CredentialRequest<NKodeCipherSuite>,
|
request: &CredentialRequest<NKodeCipherSuite>,
|
||||||
) -> Result<OpaqueLoginSession, ClientAuthError> {
|
) -> Result<OpaqueLoginSession, ClientAuthError> {
|
||||||
self.auth_db.lock().await
|
self.auth_db
|
||||||
.login_start::<K>(identifier, request.clone())
|
.login_start::<K>(identifier, request.clone())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(e))
|
.map_err(|e| ClientAuthError::Transport(e))
|
||||||
@@ -91,7 +85,7 @@ where
|
|||||||
message: &CredentialFinalization<NKodeCipherSuite>,
|
message: &CredentialFinalization<NKodeCipherSuite>,
|
||||||
) -> Result<LoggedInSession, ClientAuthError> {
|
) -> Result<LoggedInSession, ClientAuthError> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.auth_db.lock().await
|
.auth_db
|
||||||
.login_finish(session_id, message.clone())
|
.login_finish(session_id, message.clone())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientAuthError::Transport(e))?
|
.map_err(|e| ClientAuthError::Transport(e))?
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::server::repository::user_repo::UserRepo;
|
use crate::server::repository::user_repo::UserRepo;
|
||||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
|
|
||||||
pub struct InMemoryUserDB {
|
pub struct InMemoryUserDB {
|
||||||
key_session: HashMap<Uuid, KeyLoggedInSession>,
|
key_session: Arc<Mutex<HashMap<Uuid, KeyLoggedInSession>>>,
|
||||||
code_session: HashMap<Uuid, CodeLoggedInSession>,
|
code_session: Arc<Mutex<HashMap<Uuid, CodeLoggedInSession>>>,
|
||||||
code_data: HashMap<Email, CodeLoginData>,
|
code_data: Arc<Mutex<HashMap<Email, CodeLoginData>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InMemoryUserDB {
|
impl InMemoryUserDB {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
key_session: HashMap::new(),
|
key_session: Arc::new(Mutex::new(HashMap::new())),
|
||||||
code_session: HashMap::new(),
|
code_session: Arc::new(Mutex::new(HashMap::new())),
|
||||||
code_data: HashMap::new(),
|
code_data: Arc::new(Mutex::new(HashMap::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,40 +29,39 @@ impl Default for InMemoryUserDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl UserRepo for InMemoryUserDB {
|
impl UserRepo for InMemoryUserDB {
|
||||||
fn get_key_session(&mut self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
async fn get_key_session(&self, session_id: &Uuid) -> Result<KeyLoggedInSession, String> {
|
||||||
self.key_session
|
self.key_session.lock().await
|
||||||
.get(&session_id)
|
.get(&session_id)
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or_else(|| format!("key session not found for session_id={}", session_id))
|
.ok_or_else(|| format!("key session not found for session_id={}", session_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_code_session(&mut self, session_id: &Uuid) -> Result<CodeLoggedInSession, String> {
|
async fn get_code_session(&self, session_id: &Uuid) -> Result<CodeLoggedInSession, String> {
|
||||||
self.code_session
|
self.code_session.lock().await
|
||||||
.get(&session_id)
|
.get(&session_id)
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or_else(|| format!("code session not found for session_id={}", session_id))
|
.ok_or_else(|| format!("code session not found for session_id={}", session_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_key_session(&mut self, session: KeyLoggedInSession) -> Result<(), String> {
|
async fn set_key_session(&self, session: KeyLoggedInSession) -> Result<(), String> {
|
||||||
// Assumes KeyLoggedInSession has a session_id: Uuid field (common pattern)
|
self.key_session.lock().await.insert(session.0.session_id, session);
|
||||||
self.key_session.insert(session.0.session_id, session);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_code_session(&mut self, session: CodeLoggedInSession) -> Result<(), String> {
|
async fn set_code_session(&self, session: CodeLoggedInSession) -> Result<(), String> {
|
||||||
// Assumes CodeLoggedInSession has a session_id: Uuid field (common pattern)
|
self.code_session.lock().await.insert(session.0.session_id, session);
|
||||||
self.code_session.insert(session.0.session_id, session);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_code_login_data(&mut self, email: Email, data: CodeLoginData) -> Result<(), String> {
|
async fn set_code_login_data(&self, email: Email, data: CodeLoginData) -> Result<(), String> {
|
||||||
self.code_data.insert(email, data);
|
self.code_data.lock().await.insert(email, data);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_code_login_data(&mut self, email: &Email) -> Result<CodeLoginData, String> {
|
async fn get_code_login_data(&self, email: &Email) -> Result<CodeLoginData, String> {
|
||||||
self.code_data
|
self.code_data.lock().await
|
||||||
.get(email)
|
.get(email)
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or_else(|| "code login data not found for email".to_string())
|
.ok_or_else(|| "code login data not found for email".to_string())
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
use crate::shared::models::app::{CodeLoggedInSession, CodeLoginData, KeyLoggedInSession};
|
||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
pub trait UserRepo {
|
pub trait UserRepo {
|
||||||
fn get_key_session(&mut self, session_id: &Uuid) -> Result<KeyLoggedInSession, String>;
|
async fn get_key_session(&self, session_id: &Uuid) -> Result<KeyLoggedInSession, String>;
|
||||||
fn get_code_session(&mut self, session_id: &Uuid) -> Result<CodeLoggedInSession, String>;
|
async fn get_code_session(&self, session_id: &Uuid) -> Result<CodeLoggedInSession, String>;
|
||||||
|
|
||||||
fn set_key_session(&mut self, session: KeyLoggedInSession) -> Result<(), String>;
|
async fn set_key_session(&self, session: KeyLoggedInSession) -> Result<(), String>;
|
||||||
fn set_code_session(&mut self, session: CodeLoggedInSession) -> Result<(), String>;
|
async fn set_code_session(&self, session: CodeLoggedInSession) -> Result<(), String>;
|
||||||
|
|
||||||
fn set_code_login_data(&mut self, email: Email, data: CodeLoginData) -> Result<(), String>;
|
async fn set_code_login_data(&self, email: Email, data: CodeLoginData) -> Result<(), String>;
|
||||||
fn get_code_login_data(&mut self, email: &Email) -> Result<CodeLoginData, String>;
|
async fn get_code_login_data(&self, email: &Email) -> Result<CodeLoginData, String>;
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,6 @@ use uuid::Uuid;
|
|||||||
use crate::shared::models::email::Email;
|
use crate::shared::models::email::Email;
|
||||||
use crate::shared::models::opaque::{OpaqueSessionKey, UserSecretKey};
|
use crate::shared::models::opaque::{OpaqueSessionKey, UserSecretKey};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LoggedInSession {
|
pub struct LoggedInSession {
|
||||||
pub(crate) session_id: Uuid,
|
pub(crate) session_id: Uuid,
|
||||||
@@ -73,4 +72,3 @@ pub trait AuthAPI {
|
|||||||
async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String>;
|
async fn is_code_registered(&self, key_login_session: &KeyLoggedInSession) -> Result<bool, String>;
|
||||||
async fn get_policy(&self) -> Result<NKodePolicy, String>;
|
async fn get_policy(&self) -> Result<NKodePolicy, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use std::{fmt, str::FromStr};
|
use std::fmt;
|
||||||
|
|
||||||
use email_address::{EmailAddress, Options};
|
use email_address::{EmailAddress, Options};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
@@ -18,11 +17,8 @@ impl Email {
|
|||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
return Err(EmailError::Empty);
|
return Err(EmailError::Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strict "address only" validation (no "Name <a@b.com>")
|
|
||||||
EmailAddress::parse_with_options(s, Options::default().without_display_text())
|
EmailAddress::parse_with_options(s, Options::default().without_display_text())
|
||||||
.map_err(|_| EmailError::InvalidFormat)?;
|
.map_err(|_| EmailError::InvalidFormat)?;
|
||||||
|
|
||||||
Ok(Self(s.to_owned()))
|
Ok(Self(s.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,63 +44,8 @@ impl Email {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- std traits ---- */
|
|
||||||
|
|
||||||
impl fmt::Display for Email {
|
impl fmt::Display for Email {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str(self.as_str())
|
f.write_str(self.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Email {
|
|
||||||
type Err = EmailError;
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
Email::new(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<String> for Email {
|
|
||||||
type Error = EmailError;
|
|
||||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
|
||||||
Email::new(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&str> for Email {
|
|
||||||
type Error = EmailError;
|
|
||||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
|
||||||
Email::new(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&[u8]> for Email {
|
|
||||||
type Error = EmailError;
|
|
||||||
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
|
|
||||||
Email::from_bytes(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Vec<u8>> for Email {
|
|
||||||
type Error = EmailError;
|
|
||||||
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
|
||||||
Email::from_bytes(&value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<str> for Email {
|
|
||||||
fn as_ref(&self) -> &str {
|
|
||||||
self.as_str()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<[u8]> for Email {
|
|
||||||
fn as_ref(&self) -> &[u8] {
|
|
||||||
self.as_bytes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Email> for Vec<u8> {
|
|
||||||
fn from(value: Email) -> Self {
|
|
||||||
value.into_bytes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ async fn opaque_key_registration_and_login_roundtrip() {
|
|||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let server_setup = NKodeServerSetup::new(&mut rng);
|
let server_setup = NKodeServerSetup::new(&mut rng);
|
||||||
let server = InMemoryKeyServer::new(server_setup);
|
let server = InMemoryKeyServer::new(server_setup);
|
||||||
let auth_reg = OpaqueAuthRegister::new(server.clone());
|
let auth_reg = OpaqueAuthRegister::new(server);
|
||||||
let auth_data = AuthenticationData::from_secret_key("a@b.com", b"supersecret16bytes");
|
let auth_data = AuthenticationData::from_secret_key("a@b.com", b"supersecret16bytes");
|
||||||
auth_reg.register(&auth_data).await.expect("registration should succeed");
|
auth_reg.register(&auth_data).await.expect("registration should succeed");
|
||||||
let login_reg = OpaqueAuthLogin::new(server);
|
let login_reg = OpaqueAuthLogin::new(server);
|
||||||
let _ =login_reg.login(&auth_data)
|
let _ =login_reg.login(&auth_data)
|
||||||
.await
|
.await
|
||||||
.expect("login should succeed");
|
.expect("login should succeed");
|
||||||
|
// assert!(!session_key.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
Reference in New Issue
Block a user