This commit is contained in:
Joshua Perry 2024-06-19 23:01:01 +01:00
parent 13f8a8214d
commit 04de502f42
2 changed files with 40 additions and 40 deletions

View File

@ -1,33 +1,33 @@
pub mod db;
use std::collections::VecDeque;
use anyhow::Result;
use axum::{
extract::Path,
body::Body, response::{IntoResponse, Response}, routing::{get, post}, Json, Router
};
use futures::{stream::{self, StreamExt, TryStreamExt}, FutureExt};
use futures::stream::{self, StreamExt, TryStreamExt};
use serde::{Deserialize, Serialize};
use crate::ApiResult;
use db::{get_database, get_users, LogEntry, Mole, User};
use http::{header::HeaderMap, StatusCode};
use http::StatusCode;
use mongodb::bson::{doc, oid::ObjectId, to_document, Document};
use serde_json::json;
pub fn router() -> Router {
Router::new()
.route("/sign-in/:username",
get(get_sign_in))
.route("/sign-in",
get(get_sign_in)
.post(post_sign_in)
post(post_sign_in)
)
.route("/sign-up",
post(post_sign_up))
.route("/sign-out",
post(post_sign_out))
.route("/backup",
.route("/sign-out/:api",
get(get_sign_out))
.route("/backup/:api",
post(post_backup)
)
.route("/restore",
.route("/restore/:api",
get(get_restore)
)
}
@ -49,10 +49,10 @@ struct BackupData {
logs: Vec<LogEntry>,
}
async fn get_sign_in(Json(body): Json<User>) -> ApiResult {
async fn get_sign_in(Path(username): Path<String>) -> ApiResult {
let db = get_users().await?;
let query = doc! {
"$expr": { "$eq": ["$username", body.username] }
"$expr": { "$eq": ["$username", username] }
};
match db.find_one(query, None).await? {
@ -66,7 +66,9 @@ async fn get_sign_in(Json(body): Json<User>) -> ApiResult {
None => {
Ok(Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("User does not exist"))?)
.body(Json(json!({
"_error": "User does not exist"
})).into_response().into_body())?)
}
}
}
@ -101,47 +103,45 @@ async fn post_sign_in(Json(body): Json<User>) -> ApiResult {
_ => {
Ok(Response::builder()
.status(StatusCode::UNAUTHORIZED)
.body(Body::from("Username or password is incorrect"))?)
.body(Json(json!({
"_error": "Username or password is incorrect"
})).into_response().into_body())?)
},
}
}
async fn post_sign_up(Json(body): Json<User>) -> ApiResult {
let db = get_users().await?;
let auth = body.clone().auth.unwrap_or_default();
let query = doc! {
"$expr": {
"$and": [
{ "$eq": ["$username", &body.username] },
{ "$eq": ["$_auth._hash", &auth.hash]},
{ "$eq": ["$_auth._salt", &auth.salt]}
]
}
"$expr": { "$eq": ["$username", &body.username] }
};
match db.count_documents(query, None).await? {
count if count != 0 => {
Ok(Response::builder()
.status(StatusCode::NOT_ACCEPTABLE)
.body(Body::from("Username is already taken"))?)
.body(Json(json!({
"_error": "Username is already taken"
})).into_response().into_body())?)
},
_ => {
db.insert_one(body, None).await?;
Ok(Response::builder()
.status(StatusCode::CREATED)
.body(Body::from("Account created successfully"))?)
.body(Json(json!({
"_success": "Account created successfully"
})).into_response().into_body())?)
}
}
}
async fn post_sign_out(headers: HeaderMap) -> ApiResult {
async fn get_sign_out(Path(api): Path<String>) -> ApiResult {
let db = get_users().await?;
let api = headers["api_key"].to_str()?;
let query = doc! {
"$expr": { "$eq": ["$_auth._api", ObjectId::parse_str(api)?] }
"$expr": { "$eq": ["$_auth._api", ObjectId::parse_str(&api)?] }
};
let update = doc! {
"$unset": {
@ -149,25 +149,28 @@ async fn post_sign_out(headers: HeaderMap) -> ApiResult {
}
};
match auth(api).await? {
match auth(&api).await? {
Some(_user) => {
db.update_one(query, update, None).await?;
Ok(Response::builder()
.status(StatusCode::OK)
.body(Body::from("Sign out successful"))?)
.body(Json(json!({
"_success": "Sign out successful"
})).into_response().into_body())?)
},
None => {
Ok(Response::builder()
.status(StatusCode::NOT_ACCEPTABLE)
.body(Body::from("User does not exist"))?)
.body(Json(json!({
"_error": "User does not exist"
})).into_response().into_body())?)
},
}
}
async fn get_restore(headers: HeaderMap) -> ApiResult {
let api = headers["api_key"].to_str()?;
async fn get_restore(Path(api): Path<String>) -> ApiResult {
let db = &get_database().await?;
match auth(api).await? {
match auth(&api).await? {
Some(user) => {
let moles: Vec<Mole> = db.collection::<Mole>("moles")
.find(doc! { "_user_id": user.id }, None).await?.try_collect().await?;
@ -195,10 +198,9 @@ async fn get_restore(headers: HeaderMap) -> ApiResult {
}
}
async fn post_backup(headers: HeaderMap, Json(user_data): Json<BackupData>) -> ApiResult {
let api = headers["api_key"].to_str()?;
async fn post_backup(Path(api): Path<String>, Json(user_data): Json<BackupData>) -> ApiResult {
match auth(api).await? {
match auth(&api).await? {
Some(_user) => {
let _ = backup_docs_if_new(user_data.moles, "moles").await;
let _ = backup_docs_if_new(user_data.logs, "logs").await;

View File

@ -30,8 +30,6 @@ pub struct Mole {
pub id: Option<ObjectId>,
#[serde(rename="_user_id")]
pub user_id: ObjectId,
#[serde(rename="_image_path", skip_serializing_if = "Option::is_none")]
pub image_path: Option<String>,
pub location: Location,
}