From 9d2b6ee10ec5359cc91769d430485c8c869ba1a8 Mon Sep 17 00:00:00 2001 From: Akshay Date: Thu, 24 Dec 2020 10:51:40 +0530 Subject: monorepo --- src/bin/server.rs | 94 ---------------------------- src/handlers/cart_items.rs | 107 -------------------------------- src/handlers/mod.rs | 5 -- src/handlers/product.rs | 138 ------------------------------------------ src/handlers/rating.rs | 91 ---------------------------- src/handlers/smoke.rs | 15 ----- src/handlers/users.rs | 148 --------------------------------------------- src/lib.rs | 10 --- src/models.rs | 97 ----------------------------- src/schema.rs | 61 ------------------- 10 files changed, 766 deletions(-) delete mode 100644 src/bin/server.rs delete mode 100644 src/handlers/cart_items.rs delete mode 100644 src/handlers/mod.rs delete mode 100644 src/handlers/product.rs delete mode 100644 src/handlers/rating.rs delete mode 100644 src/handlers/smoke.rs delete mode 100644 src/handlers/users.rs delete mode 100644 src/lib.rs delete mode 100644 src/models.rs delete mode 100644 src/schema.rs (limited to 'src') diff --git a/src/bin/server.rs b/src/bin/server.rs deleted file mode 100644 index 7c67e4f..0000000 --- a/src/bin/server.rs +++ /dev/null @@ -1,94 +0,0 @@ -use actix_cors::Cors; -use actix_identity::{CookieIdentityPolicy, IdentityService}; -use actix_web::middleware; -use actix_web::{web, App, HttpServer}; -use diesel::r2d2::{ConnectionManager, Pool}; -use diesel::MysqlConnection; -use furby::handlers::smoke::manual_hello; -use furby::handlers::{cart_items, product, rating, users}; -use rand::Rng; - -#[actix_web::main] -async fn main() -> std::io::Result<()> { - pretty_env_logger::init(); - - let db_url = env!("DATABASE_URL"); - let manager = ConnectionManager::::new(db_url); - let pool = Pool::builder() - .build(manager) - .expect("Failed to create pool."); - - let private_key = rand::thread_rng().gen::<[u8; 32]>(); - HttpServer::new(move || { - App::new() - .wrap(IdentityService::new( - CookieIdentityPolicy::new(&private_key) - .name("user-login") - .domain("127.0.0.1") - .path("/") - .same_site(actix_web::cookie::SameSite::None) - .http_only(true) - .secure(false), - )) - .wrap( - Cors::default() - .allowed_origin("http://127.0.0.1:8000") - .allowed_origin("http://localhost:8000") - .allow_any_method() - .allow_any_header(), - ) - .wrap( - middleware::DefaultHeaders::new() - .header("Access-Control-Allow-Credentials", "true") - .header("Access-Control-Expose-Headers", "set-cookie"), - ) - .wrap(middleware::Logger::default()) - .data(pool.clone()) - .service( - web::scope("/user") - .route("/existing", web::post().to(users::name_exists)) - .route("/login", web::post().to(users::login)) - .route("/{uname}", web::get().to(users::user_details)) - .route("/new", web::post().to(users::new_user)) - .route( - "/change_password", - web::post().to(users::change_password), - ), - ) - .service( - web::scope("/product") - .route("/catalog", web::get().to(product::get_all_products)) - .route("/new", web::post().to(product::new_product)) - .route("/{id}", web::get().to(product::product_details)) - .route( - "/reviews/{id}", - web::get().to(product::get_product_reviews), - ) - .route( - "/update_product/{id}", - web::post().to(product::update_product), - ), - ) - .service( - web::scope("/cart") - .route( - "/items", - web::get().to(cart_items::get_user_cart_items), - ) - .route("/add", web::post().to(cart_items::add_to_cart)) - .route( - "/remove", - web::post().to(cart_items::remove_from_cart), - ), - ) - .service( - web::scope("/rating") - .route("/add", web::post().to(rating::add_rating)) - .route("/remove", web::post().to(rating::remove_rating)), - ) - .route("/hey", web::get().to(manual_hello)) - }) - .bind("127.0.0.1:7878")? - .run() - .await -} diff --git a/src/handlers/cart_items.rs b/src/handlers/cart_items.rs deleted file mode 100644 index 25baaeb..0000000 --- a/src/handlers/cart_items.rs +++ /dev/null @@ -1,107 +0,0 @@ -use crate::models::{AddCartItem, CartItem, Customer, Product}; -use crate::schema::product::dsl as prod; -use crate::schema::{cart_items::dsl::*, customer::dsl::*}; -use crate::TPool; - -use actix_identity::Identity; -use actix_web::{web, HttpResponse, Responder}; -use diesel::prelude::*; -use log::{error, info}; -use serde::Deserialize; - -pub async fn add_to_cart( - cookie: Identity, - item_id: String, - pool: web::Data, -) -> impl Responder { - let item_details = item_id.parse::().unwrap_or(-1); - info!("Add to cart hit: {:?}", item_details); - info!("[cart] Current user: {:?}", cookie.identity()); - let conn = pool.get().unwrap(); - if let Some(uname) = cookie.identity() { - let selected_user = customer - .filter(username.eq(&uname)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to DB"); - let new_cart_item = AddCartItem { - cart_id: selected_user.id, - product_id: item_details, - }; - info!( - "cart id: {:?}, product id {:?}", - selected_user.id, item_details - ); - diesel::insert_into(cart_items) - .values((cart_id.eq(selected_user.id), product_id.eq(item_details))) - .execute(&conn) - .expect("Coundn't connect to DB"); - HttpResponse::Ok().body("Inserted successfully!") - } else { - error!("Unauthorized add to cart action!"); - return HttpResponse::Unauthorized() - .body("Need to be logged in to add to cart!"); - } -} - -pub async fn remove_from_cart( - cookie: Identity, - item_id: String, - pool: web::Data, -) -> impl Responder { - info!("Remove from cart hit: {:?}", item_id); - let item_details = item_id.parse::().unwrap_or(-1); - let conn = pool.get().unwrap(); - if let Some(uname) = cookie.identity() { - let selected_user = customer - .filter(username.eq(&uname)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to DB"); - - diesel::delete( - cart_items - .filter(cart_id.eq(selected_user.id)) - .filter(product_id.eq(item_details)), - ) - .execute(&conn) - .expect("Coundn't connect to DB"); - HttpResponse::Ok().body("Removed successfully!") - } else { - error!("Unauthorized add to cart action!"); - return HttpResponse::Unauthorized() - .body("Need to be logged in to add to cart!"); - } -} - -pub async fn get_user_cart_items( - cookie: Identity, - pool: web::Data, -) -> impl Responder { - let conn = pool.get().unwrap(); - if let Some(uname) = cookie.identity() { - let selected_user = customer - .filter(username.eq(&uname)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to DB"); - let user_cart_items = cart_items - .filter(cart_id.eq(selected_user.id)) - .load::(&conn) - .expect("Couldn't connect to DB"); - let cart_products = user_cart_items - .into_iter() - .map(|item| { - prod::product - .filter(prod::id.eq(item.product_id)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to db") - }) - .collect::>(); - return HttpResponse::Ok().json(&cart_products); - } else { - return HttpResponse::Unauthorized() - .body("Need to be logged in to add to cart!"); - } -} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs deleted file mode 100644 index 9416857..0000000 --- a/src/handlers/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod cart_items; -pub mod product; -pub mod rating; -pub mod smoke; -pub mod users; diff --git a/src/handlers/product.rs b/src/handlers/product.rs deleted file mode 100644 index 41a47a0..0000000 --- a/src/handlers/product.rs +++ /dev/null @@ -1,138 +0,0 @@ -use crate::models::{Customer, NewProduct, Product, Rating, UpdateProduct}; -use crate::schema::customer::dsl as cust; -use crate::schema::product::dsl::*; -use crate::schema::rating::dsl as rating; -use crate::TPool; - -use actix_web::{web, HttpResponse, Responder}; -use chrono::naive::NaiveDate; -use diesel::prelude::*; -use log::{error, info}; -use serde::{Deserialize, Serialize}; - -pub async fn new_product( - pool: web::Data, - item: web::Json, -) -> impl Responder { - info!("New product hit: {:?}", item.name); - let conn = pool.get().unwrap(); - diesel::insert_into(product) - .values(item.into_inner()) - .execute(&conn) - .expect("Coundn't connect to DB"); - HttpResponse::Ok().body("Inserted successfully!") -} - -pub async fn product_details( - pool: web::Data, - product_id: web::Path, -) -> impl Responder { - let conn = pool.get().unwrap(); - let product_id = product_id.into_inner(); - info!("Fetching product details for {}", product_id); - let selected_product = product - .filter(id.eq(&product_id)) - .limit(1) - .first::(&conn); - match selected_product { - Ok(m) => { - info!("Found product: {}", product_id); - HttpResponse::Ok().json(m) - } - Err(_) => { - error!("Product not found: {}", product_id); - HttpResponse::NotFound().finish() - } - } -} - -pub async fn update_product( - pool: web::Data, - product_id: web::Path, - product_details: web::Json, -) -> impl Responder { - let conn = pool.get().unwrap(); - let product_id = product_id.into_inner(); - let product_details = product_details.into_inner(); - info!("Updating product: {:?}", product_id); - match diesel::update(product.filter(id.eq(product_id))) - .set(( - name.eq(product_details.name), - kind.eq(product_details.kind), - price.eq(product_details.price), - description.eq(product_details.description), - )) - .execute(&conn) - { - Ok(_) => { - return HttpResponse::Ok().body("Changed product successfully") - } - _ => { - return HttpResponse::InternalServerError() - .body("Unable to update record") - } - } -} - -pub async fn get_all_products(pool: web::Data) -> impl Responder { - let conn = pool.get().unwrap(); - info!("Generating and returning catalog ..."); - match product.load::(&conn) { - Ok(products) => return HttpResponse::Ok().json(&products), - Err(_) => { - return HttpResponse::InternalServerError() - .body("Unable to fetch product catalog") - } - } -} - -#[derive(Serialize, Deserialize, Debug)] -struct ProductRating { - pub comment_text: Option, - pub comment_date: NaiveDate, - pub product_name: String, - pub customer_name: String, - pub stars: Option, -} - -pub async fn get_product_reviews( - pool: web::Data, - product_id: web::Path, -) -> impl Responder { - let conn = pool.get().unwrap(); - info!("Fetching product reviews for {}", product_id); - let pid = product_id.into_inner(); - let rating_entries = rating::rating - .filter(rating::product_id.eq(pid)) - .load::(&conn) - .expect("Couldn't connect to DB"); - let json_ratings = rating_entries - .into_iter() - .map(move |p| { - let selected_product = product - .filter(id.eq(&p.product_id.unwrap())) - .limit(1) - .first::(&conn) - .unwrap() - .name - .clone(); - - let selected_customer = cust::customer - .filter(cust::id.eq(&p.customer_id.unwrap())) - .limit(1) - .first::(&conn) - .unwrap() - .username - .clone(); - - ProductRating { - comment_text: p.comment_text, - comment_date: p.comment_date.unwrap(), - product_name: selected_product, - customer_name: selected_customer, - stars: p.stars, - } - }) - .collect::>(); - return HttpResponse::Ok().json(&json_ratings); -} diff --git a/src/handlers/rating.rs b/src/handlers/rating.rs deleted file mode 100644 index dfbeb3e..0000000 --- a/src/handlers/rating.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::models::{AddRating, Customer, Rating}; -use crate::schema::rating::dsl as rating; -use crate::schema::{customer::dsl::*, product::dsl::*}; -use crate::TPool; - -use actix_identity::Identity; -use actix_web::{web, HttpResponse, Responder}; -use diesel::prelude::*; -use log::{error, info}; -use serde::Deserialize; - -#[derive(Deserialize, Debug)] -pub struct AddRatingJson { - pub comment_text: Option, - pub stars: Option, - pub product_id: i32, -} - -pub async fn add_rating( - cookie: Identity, - rating_details: web::Json, - pool: web::Data, -) -> impl Responder { - info!("Add rating hit: {:?}", rating_details.product_id); - info!("{:?}", cookie.identity()); - let conn = pool.get().unwrap(); - if let Some(uname) = cookie.identity() { - let selected_user = customer - .filter(username.eq(&uname)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to DB"); - let rating_details = rating_details.into_inner(); - let new_rating = AddRating { - comment_text: rating_details.comment_text, - stars: rating_details.stars, - product_id: rating_details.product_id, - customer_id: selected_user.id, - }; - diesel::insert_into(rating::rating) - .values(new_rating) - .execute(&conn) - .expect("Coundn't connect to DB"); - HttpResponse::Ok().body("Inserted rating successfully!") - } else { - error!("Unauthorized add rating action!"); - return HttpResponse::Unauthorized() - .body("Need to be logged in to add rating!"); - } -} - -#[derive(Deserialize, Debug)] -pub struct RemoveRating { - rating_id: i32, -} - -pub async fn remove_rating( - cookie: Identity, - rating_details: web::Json, - pool: web::Data, -) -> impl Responder { - info!("Remove rating hit: {:?}", rating_details.rating_id); - let conn = pool.get().unwrap(); - if let Some(uname) = cookie.identity() { - let selected_user = customer - .filter(username.eq(&uname)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to DB"); - - diesel::delete( - rating::rating - .filter(rating::customer_id.eq(selected_user.id)) - .filter(rating::id.eq(rating_details.rating_id)), - ) - .execute(&conn) - .expect("Coundn't connect to DB"); - HttpResponse::Ok().body("Removed successfully!") - } else { - error!("Unauthorized add to cart action!"); - return HttpResponse::Unauthorized() - .body("Need to be logged in to add to cart!"); - } -} - -// pub async fn get_product_reviews( -// product: web::Json, -// pool: web::Data, -// ) -> impl Responder { -// unimplemented!() -// } diff --git a/src/handlers/smoke.rs b/src/handlers/smoke.rs deleted file mode 100644 index d0a1038..0000000 --- a/src/handlers/smoke.rs +++ /dev/null @@ -1,15 +0,0 @@ -use actix_web::{get, post, HttpResponse, Responder}; - -#[get("/")] -async fn hello() -> impl Responder { - HttpResponse::Ok().body("Hello world!") -} - -#[post("/echo")] -async fn echo(req_body: String) -> impl Responder { - HttpResponse::Ok().body(req_body) -} - -pub async fn manual_hello() -> impl Responder { - HttpResponse::Ok().body("Hey there!") -} diff --git a/src/handlers/users.rs b/src/handlers/users.rs deleted file mode 100644 index 24fb591..0000000 --- a/src/handlers/users.rs +++ /dev/null @@ -1,148 +0,0 @@ -use crate::models::{Customer, NewCustomer}; -use crate::schema::customer::dsl::*; -use crate::TPool; - -use actix_identity::Identity; -use actix_web::{web, HttpResponse, Responder}; -use bcrypt::{hash, verify, DEFAULT_COST}; -use diesel::prelude::*; -use log::{error, info}; -use serde::Deserialize; - -pub async fn new_user( - pool: web::Data, - item: web::Json, -) -> impl Responder { - info!("Creating ... {:?}", item.username); - let conn = pool.get().unwrap(); - let hashed_item = NewCustomer { - password: hash(&item.password, DEFAULT_COST).unwrap(), - ..(item.into_inner()) - }; - diesel::insert_into(customer) - .values(hashed_item) - .execute(&conn) - .expect("Coundn't connect to DB"); - HttpResponse::Ok().body("Inserted successfully!") -} - -pub async fn name_exists( - pool: web::Data, - item: String, -) -> impl Responder { - let conn = pool.get().unwrap(); - info!("target: {:?}", item); - if (customer - .filter(username.eq(&item)) - .limit(1) - .load::(&conn) - .expect("Coundn't connect to DB")) - .len() - > 0 - { - HttpResponse::Ok().body("true") - } else { - HttpResponse::Ok().body("false") - } -} - -#[derive(Deserialize)] -pub struct Login { - username: String, - password: String, -} - -pub async fn login( - pool: web::Data, - cookie: Identity, - login_details: web::Json, -) -> impl Responder { - info!("Login hit"); - if let Some(uname) = cookie.identity() { - info!("Found existing cookie: {:?}", cookie.identity()); - return HttpResponse::Ok().finish(); - } - let conn = pool.get().unwrap(); - let entered_pass = &login_details.password; - let selected_user = customer - .filter(username.eq(&login_details.username)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to DB"); - let hashed_pass = selected_user.password; - if verify(entered_pass, &hashed_pass).unwrap() { - cookie.remember(login_details.username.clone()); - info!( - "Successful login: {} {}", - selected_user.username, selected_user.email_id - ); - HttpResponse::Ok().finish() - } else { - HttpResponse::Unauthorized().finish() - } -} - -pub async fn logout(cookie: Identity) -> impl Responder { - cookie.forget(); - HttpResponse::Found().header("location", "/").finish() -} - -pub async fn user_details( - uname: web::Path, - pool: web::Data, -) -> impl Responder { - let conn = pool.get().unwrap(); - let uname = uname.into_inner(); - info!("Fetching info for: \"{}\"", uname); - let selected_user = customer - .filter(username.eq(&uname)) - .limit(1) - .first::(&conn); - match selected_user { - Ok(m) => { - info!("Found user: {}", uname); - HttpResponse::Ok().json(m) - } - Err(_) => { - error!("User not found: {}", uname); - HttpResponse::NotFound().finish() - } - } -} - -#[derive(Deserialize, Debug)] -pub struct ChangePassword { - old_password: String, - new_password: String, -} - -pub async fn change_password( - cookie: Identity, - password_details: web::Json, - pool: web::Data, -) -> impl Responder { - info!("Change password request: {:?}", password_details); - let conn = pool.get().unwrap(); - if let Some(uname) = cookie.identity() { - let entered_pass = &password_details.old_password; - let new_password = &password_details.new_password; - let selected_user = customer - .filter(username.eq(&uname)) - .limit(1) - .first::(&conn) - .expect("Couldn't connect to DB"); - let hashed_pass = selected_user.password; - if verify(entered_pass, &hashed_pass).unwrap() { - let hashed_new_password = - hash(&new_password, DEFAULT_COST).unwrap(); - diesel::update(customer.filter(id.eq(selected_user.id))) - .set(password.eq(hashed_new_password)) - .execute(&conn) - .unwrap(); - return HttpResponse::Ok().body("Changed password successfully"); - } else { - return HttpResponse::Ok().body("Invalid password"); - } - } - return HttpResponse::Unauthorized().body("Login first"); -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index d956a3f..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[macro_use] -extern crate diesel; - -pub mod handlers; -pub mod models; -pub mod schema; - -use diesel::r2d2::{self, ConnectionManager}; -use diesel::MysqlConnection; -pub type TPool = r2d2::Pool>; diff --git a/src/models.rs b/src/models.rs deleted file mode 100644 index a104209..0000000 --- a/src/models.rs +++ /dev/null @@ -1,97 +0,0 @@ -use super::schema::{cart_items, customer, product, rating, transaction}; - -use chrono::naive::{NaiveDate, NaiveDateTime}; -use diesel::{Insertable, Queryable}; -use serde::{Deserialize, Serialize}; - -/* Member */ -#[derive(Queryable, Serialize)] -pub struct Customer { - pub id: i32, - pub username: String, - pub password: String, - pub phone_number: String, - pub email_id: String, - pub address: Option, -} - -#[derive(Insertable, Deserialize)] -#[table_name = "customer"] -pub struct NewCustomer { - pub username: String, - pub password: String, - pub phone_number: String, - pub email_id: String, - - #[serde(skip_serializing_if = "Option::is_none")] - pub address: Option, -} - -/* Product */ -#[derive(Queryable, Serialize)] -pub struct Product { - pub id: i32, - pub name: String, - pub kind: Option, - pub price: f32, - pub description: Option, -} - -#[derive(Insertable, Deserialize)] -#[table_name = "product"] -pub struct NewProduct { - pub name: String, - - #[serde(skip_serializing_if = "Option::is_none")] - pub kind: Option, - pub price: f32, - - #[serde(skip_serializing_if = "Option::is_none")] - pub description: Option, -} - -#[derive(Deserialize)] -pub struct UpdateProduct { - pub name: String, - pub kind: Option, - pub price: f32, - pub description: Option, -} - -/* Cart Items */ -#[derive(Queryable, Serialize)] -pub struct CartItem { - pub cart_id: i32, - pub product_id: i32, -} - -#[derive(Insertable, Deserialize)] -#[table_name = "cart_items"] -pub struct AddCartItem { - pub cart_id: i32, - pub product_id: i32, -} - -/* Rating */ -#[derive(Queryable, Serialize)] -pub struct Rating { - pub id: i32, - pub comment_text: Option, - pub comment_date: Option, - pub product_id: Option, - pub customer_id: Option, - pub stars: Option, -} - -#[derive(Insertable, Deserialize)] -#[table_name = "rating"] -pub struct AddRating { - #[serde(skip_serializing_if = "Option::is_none")] - pub comment_text: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - pub stars: Option, - - pub product_id: i32, - pub customer_id: i32, -} diff --git a/src/schema.rs b/src/schema.rs deleted file mode 100644 index f08221a..0000000 --- a/src/schema.rs +++ /dev/null @@ -1,61 +0,0 @@ -table! { - cart_items (cart_id, product_id) { - cart_id -> Integer, - product_id -> Integer, - } -} - -table! { - customer (id) { - id -> Integer, - username -> Varchar, - password -> Varchar, - phone_number -> Varchar, - email_id -> Varchar, - address -> Nullable, - } -} - -table! { - product (id) { - id -> Integer, - name -> Varchar, - kind -> Nullable, - price -> Float, - description -> Nullable, - } -} - -table! { - rating (id) { - id -> Integer, - comment_text -> Nullable, - comment_date -> Nullable, - product_id -> Nullable, - customer_id -> Nullable, - stars -> Nullable, - } -} - -table! { - transaction (id) { - id -> Integer, - payment_type -> Varchar, - amount -> Float, - customer_id -> Nullable, - } -} - -joinable!(cart_items -> customer (cart_id)); -joinable!(cart_items -> product (product_id)); -joinable!(rating -> customer (customer_id)); -joinable!(rating -> product (product_id)); -joinable!(transaction -> customer (customer_id)); - -allow_tables_to_appear_in_same_query!( - cart_items, - customer, - product, - rating, - transaction, -); -- cgit v1.2.3