aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2020-12-16 14:30:42 +0000
committerAkshay <[email protected]>2020-12-16 14:30:42 +0000
commitf25d37318e7873bf4f5ca58bcb850bed70ae77a6 (patch)
tree3a470f463d274f31228c71eb793a912f06b09046
parent199f6bfd503901121b0cdf532a46de89b592ada0 (diff)
add product/ endpoints
-rw-r--r--src/bin/server.rs17
-rw-r--r--src/handlers/mod.rs1
-rw-r--r--src/handlers/product.rs25
-rw-r--r--src/handlers/users.rs28
-rw-r--r--src/models.rs36
-rw-r--r--src/schema.rs41
6 files changed, 117 insertions, 31 deletions
diff --git a/src/bin/server.rs b/src/bin/server.rs
index 180c5bc..601d514 100644
--- a/src/bin/server.rs
+++ b/src/bin/server.rs
@@ -5,7 +5,7 @@ use actix_web::{web, App, HttpServer};
5use diesel::r2d2::{ConnectionManager, Pool}; 5use diesel::r2d2::{ConnectionManager, Pool};
6use diesel::MysqlConnection; 6use diesel::MysqlConnection;
7use furby::handlers::smoke::manual_hello; 7use furby::handlers::smoke::manual_hello;
8use furby::handlers::{product, users}; 8use furby::handlers::{cart_items, product, users};
9use rand::Rng; 9use rand::Rng;
10 10
11#[actix_web::main] 11#[actix_web::main]
@@ -42,13 +42,26 @@ async fn main() -> std::io::Result<()> {
42 ) 42 )
43 .service( 43 .service(
44 web::scope("/product") 44 web::scope("/product")
45 .route("/{id}", web::get().to(product::product_details)) 45 .route("/catalog", web::get().to(product::get_all_products))
46 .route("/new", web::post().to(product::new_product)) 46 .route("/new", web::post().to(product::new_product))
47 .route("/{id}", web::get().to(product::product_details))
47 .route( 48 .route(
48 "/update_product/{id}", 49 "/update_product/{id}",
49 web::post().to(product::update_product), 50 web::post().to(product::update_product),
50 ), 51 ),
51 ) 52 )
53 .service(
54 web::scope("/cart")
55 .route(
56 "/items",
57 web::get().to(cart_items::get_user_cart_items),
58 )
59 .route("/add", web::post().to(cart_items::add_to_cart))
60 .route(
61 "/remove",
62 web::post().to(cart_items::remove_from_cart),
63 ),
64 )
52 .route("/hey", web::get().to(manual_hello)) 65 .route("/hey", web::get().to(manual_hello))
53 }) 66 })
54 .bind("127.0.0.1:7878")? 67 .bind("127.0.0.1:7878")?
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index 41bba8d..28591bc 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -1,3 +1,4 @@
1pub mod cart_items;
1pub mod product; 2pub mod product;
2pub mod smoke; 3pub mod smoke;
3pub mod users; 4pub mod users;
diff --git a/src/handlers/product.rs b/src/handlers/product.rs
index 60a4684..788efb3 100644
--- a/src/handlers/product.rs
+++ b/src/handlers/product.rs
@@ -1,4 +1,4 @@
1use crate::models::{NewProduct, Product}; 1use crate::models::{NewProduct, Product, UpdateProduct};
2use crate::schema::product::dsl::*; 2use crate::schema::product::dsl::*;
3use crate::TPool; 3use crate::TPool;
4 4
@@ -43,14 +43,6 @@ pub async fn product_details(
43 } 43 }
44} 44}
45 45
46#[derive(Deserialize)]
47pub struct UpdateProduct {
48 name: String,
49 kind: Option<String>,
50 price: f32,
51 description: Option<String>,
52}
53
54pub async fn update_product( 46pub async fn update_product(
55 pool: web::Data<TPool>, 47 pool: web::Data<TPool>,
56 product_id: web::Path<i32>, 48 product_id: web::Path<i32>,
@@ -78,3 +70,18 @@ pub async fn update_product(
78 } 70 }
79 } 71 }
80} 72}
73
74pub async fn get_all_products(pool: web::Data<TPool>) -> impl Responder {
75 let conn = pool.get().unwrap();
76 info!("Generating and returning catalog ...");
77 match product.load::<Product>(&conn) {
78 Ok(products) => {
79 return HttpResponse::Ok()
80 .body(serde_json::to_string(&products).unwrap())
81 }
82 Err(_) => {
83 return HttpResponse::InternalServerError()
84 .body("Unable to fetch product catalog")
85 }
86 }
87}
diff --git a/src/handlers/users.rs b/src/handlers/users.rs
index c7bc870..bff532c 100644
--- a/src/handlers/users.rs
+++ b/src/handlers/users.rs
@@ -1,5 +1,5 @@
1use crate::models::{Member, NewMember}; 1use crate::models::{Customer, NewCustomer};
2use crate::schema::members::dsl::*; 2use crate::schema::customer::dsl::*;
3use crate::TPool; 3use crate::TPool;
4 4
5use actix_identity::Identity; 5use actix_identity::Identity;
@@ -11,14 +11,14 @@ use serde::Deserialize;
11 11
12pub async fn new_user( 12pub async fn new_user(
13 pool: web::Data<TPool>, 13 pool: web::Data<TPool>,
14 item: web::Json<NewMember>, 14 item: web::Json<NewCustomer>,
15) -> impl Responder { 15) -> impl Responder {
16 let conn = pool.get().unwrap(); 16 let conn = pool.get().unwrap();
17 let hashed_item = NewMember { 17 let hashed_item = NewCustomer {
18 password: hash(&item.password, DEFAULT_COST).unwrap(), 18 password: hash(&item.password, DEFAULT_COST).unwrap(),
19 ..(item.into_inner()) 19 ..(item.into_inner())
20 }; 20 };
21 diesel::insert_into(members) 21 diesel::insert_into(customer)
22 .values(hashed_item) 22 .values(hashed_item)
23 .execute(&conn) 23 .execute(&conn)
24 .expect("Coundn't connect to DB"); 24 .expect("Coundn't connect to DB");
@@ -31,10 +31,10 @@ pub async fn name_exists(
31) -> impl Responder { 31) -> impl Responder {
32 let conn = pool.get().unwrap(); 32 let conn = pool.get().unwrap();
33 info!("target: {:?}", item); 33 info!("target: {:?}", item);
34 if (members 34 if (customer
35 .filter(username.eq(&item)) 35 .filter(username.eq(&item))
36 .limit(1) 36 .limit(1)
37 .load::<Member>(&conn) 37 .load::<Customer>(&conn)
38 .expect("Coundn't connect to DB")) 38 .expect("Coundn't connect to DB"))
39 .len() 39 .len()
40 > 0 40 > 0
@@ -59,10 +59,10 @@ pub async fn login(
59 info!("Login hit"); 59 info!("Login hit");
60 let conn = pool.get().unwrap(); 60 let conn = pool.get().unwrap();
61 let entered_pass = &login_details.password; 61 let entered_pass = &login_details.password;
62 let selected_user = members 62 let selected_user = customer
63 .filter(username.eq(&login_details.username)) 63 .filter(username.eq(&login_details.username))
64 .limit(1) 64 .limit(1)
65 .first::<Member>(&conn) 65 .first::<Customer>(&conn)
66 .expect("Couldn't connect to DB"); 66 .expect("Couldn't connect to DB");
67 let hashed_pass = selected_user.password; 67 let hashed_pass = selected_user.password;
68 if verify(entered_pass, &hashed_pass).unwrap() { 68 if verify(entered_pass, &hashed_pass).unwrap() {
@@ -89,10 +89,10 @@ pub async fn user_details(
89 let conn = pool.get().unwrap(); 89 let conn = pool.get().unwrap();
90 let uname = uname.into_inner(); 90 let uname = uname.into_inner();
91 info!("Fetching info for: \"{}\"", uname); 91 info!("Fetching info for: \"{}\"", uname);
92 let selected_user = members 92 let selected_user = customer
93 .filter(username.eq(&uname)) 93 .filter(username.eq(&uname))
94 .limit(1) 94 .limit(1)
95 .first::<Member>(&conn); 95 .first::<Customer>(&conn);
96 match selected_user { 96 match selected_user {
97 Ok(m) => { 97 Ok(m) => {
98 info!("Found user: {}", uname); 98 info!("Found user: {}", uname);
@@ -121,16 +121,16 @@ pub async fn change_password(
121 if let Some(uname) = cookie.identity() { 121 if let Some(uname) = cookie.identity() {
122 let entered_pass = &password_details.old_password; 122 let entered_pass = &password_details.old_password;
123 let new_password = &password_details.new_password; 123 let new_password = &password_details.new_password;
124 let selected_user = members 124 let selected_user = customer
125 .filter(username.eq(&uname)) 125 .filter(username.eq(&uname))
126 .limit(1) 126 .limit(1)
127 .first::<Member>(&conn) 127 .first::<Customer>(&conn)
128 .expect("Couldn't connect to DB"); 128 .expect("Couldn't connect to DB");
129 let hashed_pass = selected_user.password; 129 let hashed_pass = selected_user.password;
130 if verify(entered_pass, &hashed_pass).unwrap() { 130 if verify(entered_pass, &hashed_pass).unwrap() {
131 let hashed_new_password = 131 let hashed_new_password =
132 hash(&new_password, DEFAULT_COST).unwrap(); 132 hash(&new_password, DEFAULT_COST).unwrap();
133 diesel::update(members.filter(id.eq(selected_user.id))) 133 diesel::update(customer.filter(id.eq(selected_user.id)))
134 .set(password.eq(hashed_new_password)) 134 .set(password.eq(hashed_new_password))
135 .execute(&conn) 135 .execute(&conn)
136 .unwrap(); 136 .unwrap();
diff --git a/src/models.rs b/src/models.rs
index 6af1af6..acd67a6 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -1,26 +1,32 @@
1use super::schema::{members, product}; 1use super::schema::{cart_items, customer, product, rating, transaction};
2 2
3use diesel::{Insertable, Queryable}; 3use diesel::{Insertable, Queryable};
4use serde::{Deserialize, Serialize}; 4use serde::{Deserialize, Serialize};
5 5
6/* Member */
6#[derive(Queryable, Serialize)] 7#[derive(Queryable, Serialize)]
7pub struct Member { 8pub struct Customer {
8 pub id: i32, 9 pub id: i32,
9 pub username: String, 10 pub username: String,
10 pub password: String, 11 pub password: String,
11 pub phone_number: String, 12 pub phone_number: String,
12 pub email_id: String, 13 pub email_id: String,
14 pub address: Option<String>,
13} 15}
14 16
15#[derive(Insertable, Deserialize)] 17#[derive(Insertable, Deserialize)]
16#[table_name = "members"] 18#[table_name = "customer"]
17pub struct NewMember { 19pub struct NewCustomer {
18 pub username: String, 20 pub username: String,
19 pub password: String, 21 pub password: String,
20 pub phone_number: String, 22 pub phone_number: String,
21 pub email_id: String, 23 pub email_id: String,
24
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub address: Option<String>,
22} 27}
23 28
29/* Product */
24#[derive(Queryable, Serialize)] 30#[derive(Queryable, Serialize)]
25pub struct Product { 31pub struct Product {
26 pub id: i32, 32 pub id: i32,
@@ -42,3 +48,25 @@ pub struct NewProduct {
42 #[serde(skip_serializing_if = "Option::is_none")] 48 #[serde(skip_serializing_if = "Option::is_none")]
43 pub description: Option<String>, 49 pub description: Option<String>,
44} 50}
51
52#[derive(Deserialize)]
53pub struct UpdateProduct {
54 pub name: String,
55 pub kind: Option<String>,
56 pub price: f32,
57 pub description: Option<String>,
58}
59
60/* Cart Items */
61#[derive(Queryable, Serialize)]
62pub struct CartItem {
63 pub cart_id: i32,
64 pub product_id: i32,
65}
66
67#[derive(Insertable, Deserialize)]
68#[table_name = "cart_items"]
69pub struct AddCartItem {
70 pub cart_id: i32,
71 pub product_id: i32,
72}
diff --git a/src/schema.rs b/src/schema.rs
index b6074f2..f08221a 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -1,10 +1,18 @@
1table! { 1table! {
2 members (id) { 2 cart_items (cart_id, product_id) {
3 cart_id -> Integer,
4 product_id -> Integer,
5 }
6}
7
8table! {
9 customer (id) {
3 id -> Integer, 10 id -> Integer,
4 username -> Varchar, 11 username -> Varchar,
5 password -> Varchar, 12 password -> Varchar,
6 phone_number -> Varchar, 13 phone_number -> Varchar,
7 email_id -> Varchar, 14 email_id -> Varchar,
15 address -> Nullable<Text>,
8 } 16 }
9} 17}
10 18
@@ -18,7 +26,36 @@ table! {
18 } 26 }
19} 27}
20 28
29table! {
30 rating (id) {
31 id -> Integer,
32 comment_text -> Nullable<Text>,
33 comment_date -> Nullable<Date>,
34 product_id -> Nullable<Integer>,
35 customer_id -> Nullable<Integer>,
36 stars -> Nullable<Integer>,
37 }
38}
39
40table! {
41 transaction (id) {
42 id -> Integer,
43 payment_type -> Varchar,
44 amount -> Float,
45 customer_id -> Nullable<Integer>,
46 }
47}
48
49joinable!(cart_items -> customer (cart_id));
50joinable!(cart_items -> product (product_id));
51joinable!(rating -> customer (customer_id));
52joinable!(rating -> product (product_id));
53joinable!(transaction -> customer (customer_id));
54
21allow_tables_to_appear_in_same_query!( 55allow_tables_to_appear_in_same_query!(
22 members, 56 cart_items,
57 customer,
23 product, 58 product,
59 rating,
60 transaction,
24); 61);