Skip to content

Commit

Permalink
Merge pull request #148 from sogrim/clean-backend-code
Browse files Browse the repository at this point in the history
Clean backend code
  • Loading branch information
benny-n authored Sep 24, 2022
2 parents 7a4c27d + 4f1499c commit 920c6df
Show file tree
Hide file tree
Showing 20 changed files with 334 additions and 405 deletions.
7 changes: 4 additions & 3 deletions packages/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ actix-cors = "0.6"
actix-service = "2.0"
futures-util = "0.3"
jsonwebtoken = "8.0"
jsonwebtoken-google = {version = "0.1", features = ["test-helper"]}
jsonwebtoken-google = "0.1"
env_logger = "0.9"
toml = "0.5"
dotenv = "0.15"
lazy_static = "1.4"
petgraph = "0.6"
derive_more = "0.99"

[patch.crates-io]
jsonwebtoken-google = { git = 'https://github.com/cheetah-games/jsonwebtoken-google' }
[dev-dependencies.jsonwebtoken-google]
version = "0.1"
features = ["test-helper"]
33 changes: 14 additions & 19 deletions packages/server/src/api/bo.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use std::str::FromStr;

use crate::db::Db;
use crate::error::AppError;
use crate::resources::catalog::Catalog;
use crate::{
db,
resources::{admin::Admin, course::Course},
};
use crate::resources::{admin::Admin, course::Course};
use actix_web::web::{Data, Json, Path};
use actix_web::{delete, get, put, HttpResponse};
use bson::doc;
Expand All @@ -15,11 +13,8 @@ use bson::doc;
/////////////////////////////////////////////////////////////////////////////

#[get("/courses")]
pub async fn get_all_courses(
_: Admin,
client: Data<mongodb::Client>,
) -> Result<HttpResponse, AppError> {
db::services::get_all_courses(&client)
pub async fn get_all_courses(_: Admin, db: Data<Db>) -> Result<HttpResponse, AppError> {
db.get_all_courses()
.await
.map(|courses| HttpResponse::Ok().json(courses))
}
Expand All @@ -28,9 +23,9 @@ pub async fn get_all_courses(
pub async fn get_course_by_id(
_: Admin,
id: Path<String>,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
db::services::get_course_by_id(&id, &client)
db.get_course_by_id(&id)
.await
.map(|course| HttpResponse::Ok().json(course))
}
Expand All @@ -40,11 +35,11 @@ pub async fn create_or_update_course(
_: Admin,
id: Path<String>,
course: Json<Course>,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
let course_doc = bson::to_document(&course).map_err(|e| AppError::Bson(e.to_string()))?;
let document = doc! {"$setOnInsert" : course_doc};
db::services::find_and_update_course(&id, document, &client)
db.find_and_update_course(&id, document)
.await
.map(|course| HttpResponse::Ok().json(course))
}
Expand All @@ -53,9 +48,9 @@ pub async fn create_or_update_course(
pub async fn delete_course(
_: Admin,
id: Path<String>,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
db::services::delete_course(&id, &client)
db.delete_course(&id)
.await
.map(|_| HttpResponse::Ok().finish())
}
Expand All @@ -68,10 +63,10 @@ pub async fn delete_course(
pub async fn get_catalog_by_id(
_: Admin,
id: Path<String>,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
let obj_id = bson::oid::ObjectId::from_str(&id).map_err(|e| AppError::Bson(e.to_string()))?;
db::services::get_catalog_by_id(&obj_id, &client)
db.get_catalog_by_id(&obj_id)
.await
.map(|course| HttpResponse::Ok().json(course))
}
Expand All @@ -81,12 +76,12 @@ pub async fn create_or_update_catalog(
_: Admin,
id: Path<String>,
catalog: Json<Catalog>,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
let obj_id = bson::oid::ObjectId::from_str(&id).map_err(|e| AppError::Bson(e.to_string()))?;
let catalog_doc = bson::to_document(&catalog).map_err(|e| AppError::Bson(e.to_string()))?;
let document = doc! {"$setOnInsert" : catalog_doc};
db::services::find_and_update_catalog(&obj_id, document, &client)
db.find_and_update_catalog(&obj_id, document)
.await
.map(|catalog| HttpResponse::Ok().json(catalog))
}
136 changes: 60 additions & 76 deletions packages/server/src/api/students.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use actix_web::{
web::{Data, Json, Query},
HttpMessage, HttpRequest, HttpResponse,
};
use bson::doc;
use bson::{doc, to_bson};

use crate::{
core::{degree_status::DegreeStatus, parser},
db,
db::Db,
error::AppError,
middleware::auth::Sub,
resources::{
Expand All @@ -22,70 +22,69 @@ use crate::{
#[get("/catalogs")]
pub async fn get_all_catalogs(
_: User, //TODO think about whether this is necessary
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
db::services::get_all_catalogs(&client)
db.get_all_catalogs()
.await
.map(|catalogs| HttpResponse::Ok().json(catalogs))
}

//TODO: maybe this should be "PUT" because it will ALWAYS create a user if one doesn't exist?
#[get("/students/login")]
pub async fn login(
client: Data<mongodb::Client>,
req: HttpRequest,
) -> Result<HttpResponse, AppError> {
pub async fn login(db: Data<Db>, req: HttpRequest) -> Result<HttpResponse, AppError> {
let extensions = req.extensions();
let user_id = extensions
.get::<Sub>()
.ok_or_else(|| AppError::Middleware("No sub found in request extensions".into()))?;

let document = doc! {"$setOnInsert" : User::new_document(user_id)};
let updated_user = db::services::find_and_update_user(user_id, document, &client).await?;
let user = User {
sub: user_id.to_string(),
..Default::default()
};
let document =
doc! {"$setOnInsert" : to_bson(&user).map_err(|e| AppError::Bson(e.to_string()))?};

let updated_user = db.find_and_update_user(user_id, document).await?;

Ok(HttpResponse::Ok().json(updated_user))
}

#[put("/students/catalog")]
pub async fn add_catalog(
mut user: User,
catalog_id: String,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
match &mut user.details {
Some(details) => {
let obj_id = bson::oid::ObjectId::from_str(&catalog_id)
.map_err(|e| AppError::Bson(e.to_string()))?;
let catalog = db::services::get_catalog_by_id(&obj_id, &client).await?;
details.catalog = Some(DisplayCatalog::from(catalog));
details.degree_status = DegreeStatus::default();
details.modified = true;
let updated_user = db::services::find_and_update_user(
&user.sub.clone(),
doc! {"$set" : user.into_document()},
&client,
)
.await?;
Ok(HttpResponse::Ok().json(updated_user))
}
None => Err(AppError::InternalServer("No data exists for user".into())),
}
let obj_id =
bson::oid::ObjectId::from_str(&catalog_id).map_err(|e| AppError::Bson(e.to_string()))?;
let catalog = db.get_catalog_by_id(&obj_id).await?;
user.details.catalog = Some(DisplayCatalog::from(catalog));
user.details.degree_status = DegreeStatus::default();
user.details.modified = true;
let updated_user = db
.find_and_update_user(
&user.sub.clone(),
doc! {"$set" : to_bson(&user).map_err(|e| AppError::Bson(e.to_string()))?},
)
.await?;
Ok(HttpResponse::Ok().json(updated_user))
}

#[get("/students/courses")]
pub async fn get_courses_by_filter(
_: User,
req: HttpRequest,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
let params = Query::<HashMap<String, String>>::from_query(req.query_string())
.map_err(|e| AppError::BadRequest(e.to_string()))?;
match (params.get("name"), params.get("number")) {
(Some(name), None) => {
let courses = db::services::get_courses_filtered_by_name(name, &client).await?;
let courses = db.get_courses_filtered_by_name(name).await?;
Ok(HttpResponse::Ok().json(courses))
}
(None, Some(number)) => {
let courses = db::services::get_courses_filtered_by_number(number, &client).await?;
let courses = db.get_courses_filtered_by_number(number).await?;
Ok(HttpResponse::Ok().json(courses))
}
(Some(_), Some(_)) => Err(AppError::BadRequest("Invalid query params".into())),
Expand All @@ -97,67 +96,52 @@ pub async fn get_courses_by_filter(
pub async fn add_courses(
mut user: User,
data: String,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
match &mut user.details {
Some(details) => {
details.degree_status = DegreeStatus::default();
details.degree_status.course_statuses = parser::parse_copy_paste_data(&data)?;
details.modified = true;
let updated_user = db::services::find_and_update_user(
&user.sub.clone(),
doc! {"$set" : user.into_document()},
&client,
)
.await?;
Ok(HttpResponse::Ok().json(updated_user))
}
None => Err(AppError::InternalServer("No data exists for user".into())),
}
user.details.degree_status = DegreeStatus::default();
user.details.degree_status.course_statuses = parser::parse_copy_paste_data(&data)?;
user.details.modified = true;
let updated_user = db
.find_and_update_user(
&user.sub.clone(),
doc! {"$set" : to_bson(&user).map_err(|e| AppError::Bson(e.to_string()))?},
)
.await?;
Ok(HttpResponse::Ok().json(updated_user))
}

// here "modified" becomes false
#[get("/students/degree-status")]
pub async fn compute_degree_status(
mut user: User,
client: Data<mongodb::Client>,
) -> Result<HttpResponse, AppError> {
let mut user_details = user
pub async fn compute_degree_status(mut user: User, db: Data<Db>) -> Result<HttpResponse, AppError> {
let catalog_id = user
.details
.as_mut()
.ok_or_else(|| AppError::InternalServer("No data exists for user".into()))?;

let catalog_id = user_details
.catalog
.as_ref()
.ok_or_else(|| AppError::InternalServer("No catalog chosen for user".into()))?
.id;

let catalog = db::services::get_catalog_by_id(&catalog_id, &client).await?;
let catalog = db.get_catalog_by_id(&catalog_id).await?;

user_details.modified = false;
user.details.modified = false;

let vec_courses =
db::services::get_courses_by_ids(catalog.get_all_course_ids(), &client).await?;
let malag_courses = db::services::get_all_malags(&client).await?[0]
.malag_list
.clone(); // The collection malags contain one item with the list of all malags
let vec_courses = db.get_courses_by_ids(catalog.get_all_course_ids()).await?;
let malag_courses = db.get_all_malags().await?[0].malag_list.clone(); // The collection malags contain one item with the list of all malags

let mut course_list = Vec::new();
if user.settings.compute_in_progress {
course_list = user_details.degree_status.set_in_progress_to_complete();
course_list = user.details.degree_status.set_in_progress_to_complete();
}

user_details
user.details
.degree_status
.compute(catalog, course::vec_to_map(vec_courses), malag_courses);

if user.settings.compute_in_progress {
user_details.degree_status.set_to_in_progress(course_list);
user.details.degree_status.set_to_in_progress(course_list);
}
let user_id = user.sub.clone();
let document = doc! {"$set" : user.clone().into_document()};
db::services::find_and_update_user(&user_id, document, &client).await?;
let document = doc! {"$set" : to_bson(&user).map_err(|e| AppError::Bson(e.to_string()))?};
db.find_and_update_user(&user_id, document).await?;
Ok(HttpResponse::Ok().json(user))
}

Expand All @@ -166,24 +150,24 @@ pub async fn compute_degree_status(
pub async fn update_details(
mut user: User,
details: Json<UserDetails>,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
let user_id = user.sub.clone();
user.details = Some(details.into_inner());
let document = doc! {"$set" : user.into_document()};
db::services::find_and_update_user(&user_id, document, &client).await?;
user.details = details.into_inner();
let document = doc! {"$set" : to_bson(&user).map_err(|e| AppError::Bson(e.to_string()))?};
db.find_and_update_user(&user_id, document).await?;
Ok(HttpResponse::Ok().finish())
}

#[put("/students/settings")]
pub async fn update_settings(
mut user: User,
settings: Json<UserSettings>,
client: Data<mongodb::Client>,
db: Data<Db>,
) -> Result<HttpResponse, AppError> {
let user_id = user.sub.clone();
user.settings = settings.into_inner();
let document = doc! {"$set" : user.into_document()};
db::services::find_and_update_user(&user_id, document, &client).await?;
let document = doc! {"$set" : to_bson(&user).map_err(|e| AppError::Bson(e.to_string()))?};
db.find_and_update_user(&user_id, document).await?;
Ok(HttpResponse::Ok().finish())
}
Loading

0 comments on commit 920c6df

Please sign in to comment.