Outline test cases for the authentication system
This commit is contained in:
parent
5d33f62be5
commit
2c1c19690f
|
@ -9,7 +9,7 @@ use uuid::{adapter::Hyphenated, Uuid};
|
|||
#[cfg(test)]
|
||||
use crate::errors::maybe_fail;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
pub enum AuthenticationError {
|
||||
#[error("username already exists")]
|
||||
DuplicateUsername,
|
||||
|
@ -162,11 +162,11 @@ pub trait AuthenticationDB: Send + Sync {
|
|||
session: SessionToken,
|
||||
) -> AppResult<(Username, UserId), AuthenticationError>;
|
||||
|
||||
fn get_userid(&self, username: Username) -> AppResult<UserId, AuthenticationError>;
|
||||
fn get_userid(&self, username: &Username) -> AppResult<UserId, AuthenticationError>;
|
||||
|
||||
fn get_username(&self, userid: UserId) -> AppResult<Username, AuthenticationError>;
|
||||
fn get_username(&self, userid: &UserId) -> AppResult<Username, AuthenticationError>;
|
||||
|
||||
fn list_users(&self) -> AppResult<Vec<Username>, AuthenticationError>;
|
||||
fn list_users(&self) -> AppResult<Vec<UserId>, AuthenticationError>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -282,7 +282,7 @@ impl AuthenticationDB for MemoryAuth {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_userid(&self, username: Username) -> AppResult<UserId, AuthenticationError> {
|
||||
fn get_userid(&self, username: &Username) -> AppResult<UserId, AuthenticationError> {
|
||||
Ok(self
|
||||
.users
|
||||
.get(&username)
|
||||
|
@ -290,7 +290,7 @@ impl AuthenticationDB for MemoryAuth {
|
|||
.ok_or(AuthenticationError::UserNotFound))
|
||||
}
|
||||
|
||||
fn get_username(&self, userid: UserId) -> AppResult<Username, AuthenticationError> {
|
||||
fn get_username(&self, userid: &UserId) -> AppResult<Username, AuthenticationError> {
|
||||
Ok(self
|
||||
.inverse_users
|
||||
.get(&userid)
|
||||
|
@ -298,10 +298,91 @@ impl AuthenticationDB for MemoryAuth {
|
|||
.ok_or(AuthenticationError::UserNotFound))
|
||||
}
|
||||
|
||||
fn list_users(&self) -> AppResult<Vec<Username>, AuthenticationError> {
|
||||
ok(self.users.keys().cloned().collect::<Vec<Username>>())
|
||||
fn list_users(&self) -> AppResult<Vec<UserId>, AuthenticationError> {
|
||||
ok(self.inverse_users.keys().cloned().collect::<Vec<UserId>>())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {}
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
fn with_memory_db<F>(test: F)
|
||||
where
|
||||
F: Fn(Box<dyn AuthenticationDB>),
|
||||
{
|
||||
let authdb: Box<MemoryAuth> = Box::new(Default::default());
|
||||
test(authdb);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_create_a_user() {
|
||||
fn test_case(mut authdb: Box<dyn AuthenticationDB>) {
|
||||
let username = Username::from("shephard");
|
||||
let userid = authdb
|
||||
.create_user(username.clone())
|
||||
.expect("no fatal errors")
|
||||
.expect("creation should succeed");
|
||||
assert_eq!(authdb.get_userid(&username).unwrap(), Ok(userid.clone()));
|
||||
assert_eq!(authdb.get_username(&userid).unwrap(), Ok(username));
|
||||
assert!(authdb.list_users().unwrap().unwrap().contains(&userid));
|
||||
}
|
||||
with_memory_db(test_case);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_does_not_allow_duplicate_users() {
|
||||
fn test_case(mut authdb: Box<dyn AuthenticationDB>) {
|
||||
let username = Username::from("shephard");
|
||||
let _ = authdb
|
||||
.create_user(username.clone())
|
||||
.expect("no fatal errors")
|
||||
.expect("creation should succeed");
|
||||
assert_eq!(
|
||||
authdb.create_user(username.clone()).unwrap(),
|
||||
Err(AuthenticationError::DuplicateUsername)
|
||||
);
|
||||
}
|
||||
with_memory_db(test_case);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_allows_multiple_invitations_per_user() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_exchanges_an_invitation_for_a_session() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_allows_multiple_sessions_per_user() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_disallows_invitation_reuse() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_identifies_a_user_by_session() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_deletes_a_user_and_invalidates_tokens() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_deletes_a_session() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_deletes_an_invitation() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ fn authenticate(
|
|||
})
|
||||
}
|
||||
|
||||
/*
|
||||
fn list_users(
|
||||
auth_ctx: Arc<RwLock<impl AuthenticationDB>>,
|
||||
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
||||
|
@ -154,6 +155,7 @@ fn list_users(
|
|||
}
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
@ -180,12 +182,19 @@ pub async fn main() {
|
|||
warp::reply::json(&vec!["authed", param.as_str()])
|
||||
});
|
||||
|
||||
/*
|
||||
let filter = list_users(auth_ctx.clone())
|
||||
.or(make_user(auth_ctx.clone()))
|
||||
.or(make_invitation(auth_ctx.clone()))
|
||||
.or(authenticate(auth_ctx.clone()))
|
||||
.or(echo_authenticated)
|
||||
.or(echo_unauthenticated);
|
||||
*/
|
||||
let filter = make_user(auth_ctx.clone())
|
||||
.or(make_invitation(auth_ctx.clone()))
|
||||
.or(authenticate(auth_ctx.clone()))
|
||||
.or(echo_authenticated)
|
||||
.or(echo_unauthenticated);
|
||||
|
||||
let server = warp::serve(filter);
|
||||
server
|
||||
|
|
Loading…
Reference in New Issue