feat(poc): add db and auth modules with terrors error chains
This commit is contained in:
64
server/crates/arbiter-terrors-poc/src/auth.rs
Normal file
64
server/crates/arbiter-terrors-poc/src/auth.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use terrors::OneOf;
|
||||
use crate::errors::{Internal, InvalidSignature, NotRegistered};
|
||||
|
||||
pub fn verify_signature(_nonce: u32, sig: &str) -> Result<(), OneOf<(InvalidSignature,)>> {
|
||||
if sig != "ok" {
|
||||
return Err(OneOf::new(InvalidSignature));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn authenticate(
|
||||
id: u32,
|
||||
sig: &str,
|
||||
) -> Result<u32, OneOf<(NotRegistered, InvalidSignature, Internal)>> {
|
||||
if id == 0 {
|
||||
return Err(OneOf::new(NotRegistered));
|
||||
}
|
||||
|
||||
let nonce = crate::db::get_nonce(id)
|
||||
.map_err(|e| e.broaden::<(NotRegistered, InvalidSignature, Internal), _>())?;
|
||||
verify_signature(nonce, sig)
|
||||
.map_err(|e| e.broaden::<(NotRegistered, InvalidSignature, Internal), _>())?;
|
||||
|
||||
Ok(nonce)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn verify_signature_ok() {
|
||||
assert!(verify_signature(42, "ok").is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_signature_bad() {
|
||||
let err = verify_signature(42, "bad").unwrap_err();
|
||||
assert!(err.narrow::<crate::errors::InvalidSignature, _>().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authenticate_success() {
|
||||
assert_eq!(authenticate(1, "ok").unwrap(), 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authenticate_not_registered() {
|
||||
let err = authenticate(0, "ok").unwrap_err();
|
||||
assert!(err.narrow::<crate::errors::NotRegistered, _>().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authenticate_invalid_signature() {
|
||||
let err = authenticate(1, "bad").unwrap_err();
|
||||
assert!(err.narrow::<crate::errors::InvalidSignature, _>().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authenticate_internal_error() {
|
||||
let err = authenticate(99, "ok").unwrap_err();
|
||||
assert!(err.narrow::<crate::errors::Internal, _>().is_ok());
|
||||
}
|
||||
}
|
||||
28
server/crates/arbiter-terrors-poc/src/db.rs
Normal file
28
server/crates/arbiter-terrors-poc/src/db.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use terrors::OneOf;
|
||||
use crate::errors::Internal;
|
||||
|
||||
// Simulates fetching a nonce from a database.
|
||||
// id=99 is a sentinel that triggers an Internal error.
|
||||
pub fn get_nonce(id: u32) -> Result<u32, OneOf<(Internal,)>> {
|
||||
if id == 99 {
|
||||
return Err(OneOf::new(Internal("db pool unavailable".into())));
|
||||
}
|
||||
Ok(42)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn get_nonce_returns_nonce_for_valid_id() {
|
||||
assert_eq!(get_nonce(1).unwrap(), 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_nonce_returns_internal_error_for_sentinel() {
|
||||
let err = get_nonce(99).unwrap_err();
|
||||
let internal = err.take::<crate::errors::Internal>();
|
||||
assert_eq!(internal.0, "db pool unavailable");
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,11 @@ pub enum ProtoError {
|
||||
}
|
||||
|
||||
// Internal terrors types
|
||||
#[derive(Debug)]
|
||||
pub struct NotRegistered;
|
||||
#[derive(Debug)]
|
||||
pub struct InvalidSignature;
|
||||
#[derive(Debug)]
|
||||
pub struct Internal(pub String);
|
||||
|
||||
impl From<NotRegistered> for ProtoError {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
mod errors;
|
||||
mod db;
|
||||
mod auth;
|
||||
|
||||
fn main() {}
|
||||
|
||||
Reference in New Issue
Block a user