implement server app
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::shared::models::opaque::PasswordFile;
|
||||
use crate::server::repository::opaque_repo::{OpaqueDatabaseRepo, AuthRepoError};
|
||||
use tokio::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct InMemoryOpaqueDB {
|
||||
key_entries: HashMap<KeyID, PasswordFile>,
|
||||
code_entries: HashMap<CodeID, PasswordFile>,
|
||||
key_entries: Arc<Mutex<HashMap<KeyID, PasswordFile>>>,
|
||||
code_entries: Arc<Mutex<HashMap<CodeID, PasswordFile>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
@@ -19,66 +22,67 @@ impl InMemoryOpaqueDB {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
fn code_exists(&self, identifier: &CodeID) -> bool {
|
||||
self.code_entries.contains_key(identifier)
|
||||
async fn code_exists(&self, identifier: &CodeID) -> bool {
|
||||
self.code_entries.lock().await.contains_key(identifier)
|
||||
}
|
||||
|
||||
fn key_exists(&self, identifier: &KeyID) -> bool {
|
||||
self.key_entries.contains_key(identifier)
|
||||
async fn key_exists(&self, identifier: &KeyID) -> bool {
|
||||
self.key_entries.lock().await.contains_key(identifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[async_trait]
|
||||
impl OpaqueDatabaseRepo for InMemoryOpaqueDB {
|
||||
fn new_key(
|
||||
&mut self,
|
||||
async fn new_key(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
password_file: PasswordFile,
|
||||
) -> Result<(), AuthRepoError> {
|
||||
if self.key_exists(&KeyID(identifier.to_vec())) {
|
||||
if self.key_exists(&KeyID(identifier.to_vec())).await {
|
||||
return Err(AuthRepoError::UserExists);
|
||||
}
|
||||
|
||||
self.key_entries
|
||||
self.key_entries.lock().await
|
||||
.insert(KeyID(identifier.to_vec()), password_file);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn new_code(
|
||||
&mut self,
|
||||
async fn new_code(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
password_file: PasswordFile,
|
||||
) -> Result<(), AuthRepoError> {
|
||||
if !self.has_key(identifier) {
|
||||
if !self.has_key(identifier).await {
|
||||
return Err(AuthRepoError::KeyNotRegistered);
|
||||
}
|
||||
if self.code_exists(&CodeID(identifier.to_vec())) {
|
||||
if self.code_exists(&CodeID(identifier.to_vec())).await {
|
||||
return Err(AuthRepoError::UserExists);
|
||||
}
|
||||
|
||||
self.code_entries
|
||||
self.code_entries.lock().await
|
||||
.insert(CodeID(identifier.to_vec()), password_file);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn has_code(&self, identifier: &[u8]) -> bool {
|
||||
self.code_entries
|
||||
async fn has_code(&self, identifier: &[u8]) -> bool {
|
||||
self.code_entries.lock().await
|
||||
.contains_key(&CodeID(identifier.to_vec()))
|
||||
}
|
||||
|
||||
fn has_key(&self, identifier: &[u8]) -> bool {
|
||||
self.key_entries
|
||||
async fn has_key(&self, identifier: &[u8]) -> bool {
|
||||
self.key_entries.lock().await
|
||||
.contains_key(&KeyID(identifier.to_vec()))
|
||||
}
|
||||
|
||||
fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
self.key_entries
|
||||
async fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
self.key_entries.lock().await
|
||||
.get(&KeyID(identifier.to_vec()))
|
||||
.cloned()
|
||||
.ok_or(AuthRepoError::KeyNotRegistered)
|
||||
}
|
||||
|
||||
fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
self.code_entries
|
||||
async fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError> {
|
||||
self.code_entries.lock().await
|
||||
.get(&CodeID(identifier.to_vec()))
|
||||
.cloned()
|
||||
.ok_or(AuthRepoError::CodeNotRegistered)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use opaque_ke::ServerLogin;
|
||||
use tokio::sync::Mutex;
|
||||
use uuid::Uuid;
|
||||
use crate::server::models::{LoginCache, RegCache};
|
||||
use crate::shared::models::opaque::NKodeCipherSuite;
|
||||
@@ -7,8 +11,8 @@ use crate::server::repository::opaque_repo::OpaqueSessionRepo;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InMemoryOpaqueSession {
|
||||
reg_sessions: HashMap<Uuid, RegCache>,
|
||||
login_sessions: HashMap<Uuid, LoginCache>,
|
||||
reg_sessions: Arc<Mutex<HashMap<Uuid, RegCache>>>,
|
||||
login_sessions: Arc<Mutex<HashMap<Uuid, LoginCache>>>,
|
||||
}
|
||||
|
||||
impl InMemoryOpaqueSession {
|
||||
@@ -17,28 +21,27 @@ impl InMemoryOpaqueSession {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
||||
fn new_reg_session(&mut self, identifier: &[u8]) -> Result<RegCache, String> {
|
||||
async fn new_reg_session(&self, identifier: &[u8]) -> Result<RegCache, String> {
|
||||
let cache = RegCache {
|
||||
session_id: Uuid::new_v4(),
|
||||
identifier: identifier.to_vec(),
|
||||
};
|
||||
|
||||
// Extremely unlikely collision, but keep the invariant anyway.
|
||||
if self.reg_sessions.contains_key(&cache.session_id) {
|
||||
if self.reg_sessions.lock().await.contains_key(&cache.session_id) {
|
||||
return Err("session_id collision".to_string());
|
||||
}
|
||||
|
||||
self.reg_sessions.insert(cache.session_id, RegCache {
|
||||
self.reg_sessions.lock().await.insert(cache.session_id, RegCache {
|
||||
session_id: cache.session_id,
|
||||
identifier: cache.identifier.clone(),
|
||||
});
|
||||
|
||||
Ok(cache)
|
||||
}
|
||||
|
||||
fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String> {
|
||||
async fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String> {
|
||||
self.reg_sessions
|
||||
.lock()
|
||||
.await
|
||||
.get(session_id)
|
||||
.map(|c| RegCache {
|
||||
session_id: c.session_id,
|
||||
@@ -47,15 +50,17 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
||||
.ok_or_else(|| "registration session not found".to_string())
|
||||
}
|
||||
|
||||
fn clear_reg_session(&mut self, session_id: &Uuid) -> Result<(), String> {
|
||||
async fn clear_reg_session(&self, session_id: &Uuid) -> Result<(), String> {
|
||||
self.reg_sessions
|
||||
.lock()
|
||||
.await
|
||||
.remove(session_id)
|
||||
.map(|_| ())
|
||||
.ok_or_else(|| "registration session not found".to_string())
|
||||
}
|
||||
|
||||
fn new_login_session(
|
||||
&mut self,
|
||||
async fn new_login_session(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
server_login: ServerLogin<NKodeCipherSuite>,
|
||||
) -> Result<LoginCache, String> {
|
||||
@@ -64,12 +69,10 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
||||
identifiers: identifier.to_vec(),
|
||||
server_login,
|
||||
};
|
||||
|
||||
if self.login_sessions.contains_key(&cache.session_id) {
|
||||
if self.login_sessions.lock().await.contains_key(&cache.session_id) {
|
||||
return Err("session_id collision".to_string());
|
||||
}
|
||||
|
||||
self.login_sessions.insert(
|
||||
self.login_sessions.lock().await.insert(
|
||||
cache.session_id,
|
||||
LoginCache {
|
||||
session_id: cache.session_id,
|
||||
@@ -78,12 +81,11 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
||||
server_login: cache.server_login.clone(),
|
||||
},
|
||||
);
|
||||
|
||||
Ok(cache)
|
||||
}
|
||||
|
||||
fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String> {
|
||||
self.login_sessions
|
||||
async fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String> {
|
||||
self.login_sessions.lock().await
|
||||
.get(session_id)
|
||||
.map(|c| LoginCache {
|
||||
session_id: c.session_id,
|
||||
@@ -93,8 +95,8 @@ impl OpaqueSessionRepo for InMemoryOpaqueSession {
|
||||
.ok_or_else(|| "login session not found".to_string())
|
||||
}
|
||||
|
||||
fn clear_login_session(&mut self, session_id: &Uuid) -> Result<(), String> {
|
||||
self.login_sessions
|
||||
async fn clear_login_session(&self, session_id: &Uuid) -> Result<(), String> {
|
||||
self.login_sessions.lock().await
|
||||
.remove(session_id)
|
||||
.map(|_| ())
|
||||
.ok_or_else(|| "login session not found".to_string())
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use async_trait::async_trait;
|
||||
use uuid::Uuid;
|
||||
use opaque_ke::ServerLogin;
|
||||
use crate::server::models::{LoginCache, RegCache};
|
||||
@@ -9,27 +10,29 @@ pub enum AuthRepoError {
|
||||
CodeNotRegistered,
|
||||
}
|
||||
|
||||
pub trait OpaqueDatabaseRepo {
|
||||
fn new_key(&mut self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
||||
fn new_code(&mut self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
||||
#[async_trait]
|
||||
pub trait OpaqueDatabaseRepo: Send + Sync {
|
||||
async fn new_key(&self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
||||
async fn new_code(&self, identifier: &[u8], password_file: PasswordFile) -> Result<(), AuthRepoError>;
|
||||
|
||||
fn has_code(&self, identifier: &[u8]) -> bool;
|
||||
fn has_key(&self, identifier: &[u8]) -> bool;
|
||||
async fn has_code(&self, identifier: &[u8]) -> bool;
|
||||
async fn has_key(&self, identifier: &[u8]) -> bool;
|
||||
|
||||
fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||
fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||
async fn get_key_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||
async fn get_code_passcode_file(&self, identifier: &[u8]) -> Result<PasswordFile, AuthRepoError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait OpaqueSessionRepo {
|
||||
fn new_reg_session(&mut self, identifier: &[u8]) -> Result<RegCache, String>;
|
||||
fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String>;
|
||||
fn clear_reg_session(&mut self, session_id: &Uuid) -> Result<(), String>;
|
||||
async fn new_reg_session(&self, identifier: &[u8]) -> Result<RegCache, String>;
|
||||
async fn get_reg_session(&self, session_id: &Uuid) -> Result<RegCache, String>;
|
||||
async fn clear_reg_session(&self, session_id: &Uuid) -> Result<(), String>;
|
||||
|
||||
fn new_login_session(
|
||||
&mut self,
|
||||
async fn new_login_session(
|
||||
&self,
|
||||
identifier: &[u8],
|
||||
server_login: ServerLogin<NKodeCipherSuite>,
|
||||
) -> Result<LoginCache, String>;
|
||||
fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String>;
|
||||
fn clear_login_session(&mut self, session_id: &Uuid) -> Result<(), String>;
|
||||
async fn get_login_session(&self, session_id: &Uuid) -> Result<LoginCache, String>;
|
||||
async fn clear_login_session(&self, session_id: &Uuid) -> Result<(), String>;
|
||||
}
|
||||
Reference in New Issue
Block a user