feat(api,backend): added a dummy backend, improved internal response handling and documented api http response codes
This commit is contained in:
parent
49eb7cb524
commit
3832d15887
36
src/api.rs
36
src/api.rs
|
@ -3,10 +3,10 @@ use anyhow::Result;
|
|||
use serde::Deserialize;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
|
||||
use crate::call::Call;
|
||||
use crate::call::{Call, Response, ResponseAuthenticate, ResponseRegister};
|
||||
|
||||
struct ApiState {
|
||||
tx: mpsc::Sender<(Call, oneshot::Sender<Result<()>>)>,
|
||||
tx: mpsc::Sender<(Call, oneshot::Sender<Result<Response>>)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -15,6 +15,11 @@ struct AuthenticateData {
|
|||
password: String,
|
||||
}
|
||||
|
||||
/// Possible Responses:
|
||||
/// * 200 -> Authentication was successfull
|
||||
/// * 401 -> Authentication failed (wrong password)
|
||||
/// * 404 -> User not found
|
||||
/// * 500 -> Internal Server Error
|
||||
#[post("/authenticate")]
|
||||
async fn authenticate(
|
||||
data: web::Data<ApiState>,
|
||||
|
@ -34,8 +39,15 @@ async fn authenticate(
|
|||
}
|
||||
|
||||
match rx.await.unwrap() {
|
||||
Ok(_) => HttpResponse::Ok().finish(),
|
||||
Err(_) => HttpResponse::Unauthorized().finish(),
|
||||
Ok(resp) => match resp {
|
||||
Response::Authenticate(r) => match r {
|
||||
ResponseAuthenticate::Success => HttpResponse::Ok().finish(),
|
||||
ResponseAuthenticate::UserNotFound => HttpResponse::NotFound().finish(),
|
||||
ResponseAuthenticate::WrongPassword => HttpResponse::Unauthorized().finish(),
|
||||
},
|
||||
_ => HttpResponse::InternalServerError().finish(),
|
||||
},
|
||||
_ => HttpResponse::InternalServerError().finish(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +57,10 @@ struct RegisterData {
|
|||
password: String,
|
||||
}
|
||||
|
||||
/// Possible Responses:
|
||||
/// * 200 -> User created successfully
|
||||
/// * 409 -> The requested username is already in use
|
||||
/// * 500 -> Internal Server Error
|
||||
#[post("/register")]
|
||||
async fn register(data: web::Data<ApiState>, body: web::Json<RegisterData>) -> impl Responder {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
@ -61,14 +77,20 @@ async fn register(data: web::Data<ApiState>, body: web::Json<RegisterData>) -> i
|
|||
}
|
||||
|
||||
match rx.await.unwrap() {
|
||||
Ok(_) => HttpResponse::Ok().finish(),
|
||||
Err(_) => HttpResponse::Unauthorized().finish(),
|
||||
Ok(resp) => match resp {
|
||||
Response::Register(r) => match r {
|
||||
ResponseRegister::Success => HttpResponse::Ok().finish(),
|
||||
ResponseRegister::NameAlreadyInUse => HttpResponse::Conflict().finish(),
|
||||
},
|
||||
_ => HttpResponse::InternalServerError().finish(),
|
||||
},
|
||||
_ => HttpResponse::InternalServerError().finish(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start_worker(
|
||||
port: u16,
|
||||
tx: mpsc::Sender<(Call, oneshot::Sender<Result<()>>)>,
|
||||
tx: mpsc::Sender<(Call, oneshot::Sender<Result<Response>>)>,
|
||||
) -> Result<()> {
|
||||
tokio::task::spawn(
|
||||
HttpServer::new(move || {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
use anyhow::Result;
|
||||
|
||||
use crate::call::{Response, ResponseAuthenticate, ResponseDelete, ResponseRegister};
|
||||
|
||||
pub struct Backend {}
|
||||
|
||||
impl Backend {
|
||||
pub fn register(&mut self, username: &String, password: &String) -> Result<Response> {
|
||||
println!(
|
||||
"<Dummy> Registered Account: (Username: '{}' | Password: '{}')",
|
||||
username, password
|
||||
);
|
||||
Ok(Response::Register(ResponseRegister::Success))
|
||||
}
|
||||
|
||||
pub fn authenticate(&mut self, username: &String, password: &String) -> Result<Response> {
|
||||
println!(
|
||||
"<Dummy> Authentication Request: (Username: '{}' | Password: '{}')",
|
||||
username, password
|
||||
);
|
||||
println!(" -> Accepted");
|
||||
Ok(Response::Authenticate(ResponseAuthenticate::Success))
|
||||
}
|
||||
|
||||
pub fn delete(&mut self, username: &String) -> Result<Response> {
|
||||
println!("<Dummy> Deletion Request: (Username: '{}')", username);
|
||||
println!(" -> Accepted");
|
||||
Ok(Response::Delete(ResponseDelete::Success))
|
||||
}
|
||||
|
||||
pub fn new() -> Result<Self> {
|
||||
Ok(Self {})
|
||||
}
|
||||
}
|
56
src/call.rs
56
src/call.rs
|
@ -1,6 +1,8 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use anyhow::Result;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
|
||||
use crate::backend::Backend;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Call {
|
||||
Register(String, String),
|
||||
|
@ -8,19 +10,59 @@ pub enum Call {
|
|||
Delete(String),
|
||||
}
|
||||
|
||||
async fn worker(mut rx: mpsc::Receiver<(Call, oneshot::Sender<Result<()>>)>) -> Result<()> {
|
||||
#[derive(Debug)]
|
||||
pub enum ResponseRegister {
|
||||
Success,
|
||||
NameAlreadyInUse,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ResponseAuthenticate {
|
||||
Success,
|
||||
UserNotFound,
|
||||
WrongPassword,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ResponseDelete {
|
||||
Success,
|
||||
UserNotFound,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Response {
|
||||
Register(ResponseRegister),
|
||||
Authenticate(ResponseAuthenticate),
|
||||
Delete(ResponseDelete),
|
||||
}
|
||||
|
||||
impl Call {
|
||||
async fn handle(&self, backend: &mut Backend) -> Result<Response> {
|
||||
match self {
|
||||
Self::Register(username, password) => backend.register(username, password),
|
||||
Self::Authenticate(username, password) => backend.authenticate(username, password),
|
||||
Self::Delete(username) => backend.delete(username),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn worker(
|
||||
mut rx: mpsc::Receiver<(Call, oneshot::Sender<Result<Response>>)>,
|
||||
mut backend: Backend,
|
||||
) -> Result<()> {
|
||||
loop {
|
||||
if let Some((call, tx)) = rx.recv().await {
|
||||
println!("{:#?}", call);
|
||||
tx.send(Err(anyhow::Error::msg("test"))).unwrap();
|
||||
tx.send(call.handle(&mut backend).await).unwrap();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start_worker() -> Result<mpsc::Sender<(Call, oneshot::Sender<Result<()>>)>> {
|
||||
pub async fn start_worker(
|
||||
backend: Backend,
|
||||
) -> Result<mpsc::Sender<(Call, oneshot::Sender<Result<Response>>)>> {
|
||||
let (tx, rx) = mpsc::channel(128);
|
||||
tokio::task::spawn(async {
|
||||
if let Err(e) = worker(rx).await {
|
||||
tokio::task::spawn(async move {
|
||||
if let Err(e) = worker(rx, backend).await {
|
||||
panic!("{e}");
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
mod api;
|
||||
mod backend;
|
||||
mod call;
|
||||
|
||||
use anyhow::Result;
|
||||
|
@ -7,9 +8,10 @@ use anyhow::Result;
|
|||
async fn main() -> Result<()> {
|
||||
println!("Starting BaseAuth server v0.1");
|
||||
|
||||
let tx = call::start_worker().await?;
|
||||
let backend = backend::Backend::new()?;
|
||||
|
||||
let tx = call::start_worker(backend).await?;
|
||||
api::start_worker(8080, tx).await?;
|
||||
|
||||
loop {}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue