From 31f0ae714bc49610638fa169ce70be9cda6dfcc1 Mon Sep 17 00:00:00 2001 From: Petru Date: Sat, 30 Sep 2023 21:04:51 +0300 Subject: [PATCH] issue-3. request state. user.id --- src/models/stack.rs | 10 +++---- src/models/user.rs | 5 ++-- src/routes/rating.rs | 59 ++++++++++++++++++++++------------------- src/routes/stack/add.rs | 19 ++++++------- src/startup.rs | 17 +++++++----- 5 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/models/stack.rs b/src/models/stack.rs index 8cb79b1..ad8ebf8 100644 --- a/src/models/stack.rs +++ b/src/models/stack.rs @@ -1,8 +1,8 @@ -use uuid::Uuid; use chrono::{DateTime, Utc}; use serde_derive::Deserialize; use serde_derive::Serialize; use serde_json::Value; +use uuid::Uuid; pub struct Stack { pub id: Uuid, // id - is a unique identifier for the app stack @@ -14,7 +14,6 @@ pub struct Stack { pub updated_at: DateTime, } - #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct FormData { @@ -45,8 +44,7 @@ pub struct FormData { #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct DomainList { -} +pub struct DomainList {} #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -179,8 +177,7 @@ pub struct IconLight { #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct IconDark { -} +pub struct IconDark {} #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -256,4 +253,3 @@ pub struct Service { pub shared_ports: Vec, pub main: bool, } - diff --git a/src/models/user.rs b/src/models/user.rs index 9e86a34..0c57db4 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -1,3 +1,4 @@ +#[derive(Debug, Copy, Clone)] pub struct User { - -} \ No newline at end of file + pub id: i32, +} diff --git a/src/routes/rating.rs b/src/routes/rating.rs index e930624..bc3995c 100644 --- a/src/routes/rating.rs +++ b/src/routes/rating.rs @@ -1,12 +1,12 @@ use crate::forms; use crate::models; -use crate::startup::AppState; +use crate::models::user::User; +use crate::models::RateCategory; use actix_web::{web, HttpResponse, Responder, Result}; use serde_derive::Serialize; use sqlx::PgPool; use tracing::Instrument; use uuid::Uuid; -use crate::models::RateCategory; // workflow // add, update, list, get(user_id), ACL, @@ -18,11 +18,11 @@ struct JsonResponse { status: String, message: String, code: u32, - id: Option + id: Option, } pub async fn rating( - app_state: web::Data, + user: web::ReqData, form: web::Json, pool: web::Data, ) -> Result { @@ -50,40 +50,44 @@ pub async fn rating( ); // return HttpResponse::InternalServerError().finish(); return Ok(web::Json(JsonResponse { - status : "Error".to_string(), + status: "Error".to_string(), code: 404, message: format!("Object not found {}", form.obj_id), - id: None + id: None, })); } }; - let user_id = app_state.user_id; // uuid Let's assume user_id already taken from auth - let query_span = tracing::info_span!("Search for existing vote."); match sqlx::query!( r"SELECT id FROM rating where user_id=$1 AND product_id=$2 AND category=$3 LIMIT 1", - user_id, + user.id, form.obj_id, form.category as RateCategory ) - .fetch_one(pool.get_ref()) - .instrument(query_span) - .await + .fetch_one(pool.get_ref()) + .instrument(query_span) + .await { - Ok(record) => { - tracing::info!("req_id: {} rating exists: {:?}, user: {}, product: {}, category: {:?}", - request_id, record.id, user_id, form.obj_id, form.category); + Ok(record) => { + tracing::info!( + "req_id: {} rating exists: {:?}, user: {}, product: {}, category: {:?}", + request_id, + record.id, + user.id, + form.obj_id, + form.category + ); - return Ok(web::Json(JsonResponse{ + return Ok(web::Json(JsonResponse { status: "Error".to_string(), code: 409, message: format!("Already Rated"), - id: Some(record.id) + id: Some(record.id), })); } Err(err) => { - // @todo, match the sqlx response + // @todo, match the sqlx response } } @@ -98,7 +102,7 @@ pub async fn rating( VALUES ($1, $2, $3, $4, $5, $6, NOW() at time zone 'utc', NOW() at time zone 'utc') RETURNING id "#, - user_id, + user.id, form.obj_id, form.category as models::RateCategory, form.comment, @@ -111,7 +115,6 @@ pub async fn rating( { Ok(result) => { println!("Query returned {:?}", result); - //TODO return json containing the id of the new rating tracing::info!( "req_id: {} New rating {} have been saved to database", request_id, @@ -119,20 +122,20 @@ pub async fn rating( ); Ok(web::Json(JsonResponse { - status : "ok".to_string(), + status: "ok".to_string(), code: 200, message: "Saved".to_string(), - id: Some(result.id) + id: Some(result.id), })) } Err(e) => { tracing::error!("req_id: {} Failed to execute query: {:?}", request_id, e); - Ok(web::Json(JsonResponse{ - status: "error".to_string(), - code: 500, - message: "Failed to insert".to_string(), - id: None - })) + Ok(web::Json(JsonResponse { + status: "error".to_string(), + code: 500, + message: "Failed to insert".to_string(), + id: None, + })) } } } diff --git a/src/routes/stack/add.rs b/src/routes/stack/add.rs index 67379a5..4ea14aa 100644 --- a/src/routes/stack/add.rs +++ b/src/routes/stack/add.rs @@ -1,18 +1,19 @@ -use std::io::Read; -use actix_web::{web::{Data, Bytes, Json}, HttpResponse, HttpRequest, Responder, Result}; +use crate::models::stack::FormData; use actix_web::error::{Error, JsonPayloadError, PayloadError}; +use actix_web::web::Form; +use actix_web::{ + web::{Bytes, Data, Json}, + HttpRequest, HttpResponse, Responder, Result, +}; +use chrono::Utc; use sqlx::PgPool; +use std::io::Read; +use std::str; use tracing::Instrument; use uuid::Uuid; -use chrono::Utc; -use crate::models::stack::{FormData}; -use crate::startup::AppState; -use std::str; -use actix_web::web::Form; - // pub async fn add(req: HttpRequest, app_state: Data, pool: -pub async fn add(body: Bytes) -> Result { +pub async fn add(body: Bytes) -> Result { // None::.expect("my error"); // return Err(JsonPayloadError::Payload(PayloadError::Overflow).into()); // let content_type = req.headers().get("content-type"); diff --git a/src/startup.rs b/src/startup.rs index da9b592..5999bae 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -1,22 +1,19 @@ use actix_cors::Cors; use actix_web::dev::{Server, ServiceRequest}; use actix_web::middleware::Logger; +use actix_web::HttpMessage; use actix_web::{ // http::header::HeaderName, - web::{self, Form}, + web::{self}, App, Error, HttpServer, }; use actix_web_httpauth::{extractors::bearer::BearerAuth, middleware::HttpAuthentication}; -use serde::{Deserialize, Serialize}; use sqlx::PgPool; use std::net::TcpListener; -#[derive(Serialize, Deserialize, Debug)] -pub struct AppState { - pub user_id: i32, // @todo User must be move later to actix session and obtained from auth -} +use crate::models::user::User; async fn bearer_guard( req: ServiceRequest, @@ -27,6 +24,13 @@ async fn bearer_guard( //todo get user from auth server //todo save the server in the request state //todo get the user in the rating route + let user = User { id: 1 }; + tracing::info!("authentication middleware. {user:?}"); + let existent_user = req.extensions_mut().insert(user); + if existent_user.is_some() { + tracing::error!("authentication middleware. already logged {existent_user:?}"); + //return Err(("".into(), req)); + } Ok(req) } @@ -59,7 +63,6 @@ pub fn run(listener: TcpListener, db_pool: PgPool) -> Result