diff --git a/.env b/.env index 197600e..78978ff 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ DATABASE_URL=test.db -BIND_ADDRESS=127.0.0.1:8080 +BIND_ADDRESS=127.0.0.1:7800 diff --git a/src/actions/users.rs b/src/actions/users.rs index b91bd6d..f0adcf0 100644 --- a/src/actions/users.rs +++ b/src/actions/users.rs @@ -83,9 +83,9 @@ mod query { /// <'a, B, T> where a = lifetime, B = Backend, T = SQL data types type Query<'a, B, T> = crate::schema::users::BoxedQuery<'a, B, T>; - pub fn _get_user_by_name<'a>( - user_name: &'a String, - ) -> Query<'a, Sqlite, (Text, Timestamp)> { + pub fn _get_user_by_name( + user_name: &String, + ) -> Query { use crate::schema::users::dsl::*; users .select((name, created_at)) diff --git a/src/main.rs b/src/main.rs index ac7d2d6..3716aa3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,14 +75,6 @@ async fn extract_my_obj(item: web::Json) -> HttpResponse { HttpResponse::Ok().json(item.0) // <- send response } -pub struct UserServiceImpl; - -impl UserServiceImpl { - pub fn new() -> Self { - UserServiceImpl {} - } -} - #[actix_rt::main] async fn main() -> std::io::Result<()> { std::env::set_var("RUST_LOG", "debug"); @@ -116,15 +108,28 @@ async fn main() -> std::io::Result<()> { .same_site(SameSite::Lax), )) .wrap(middleware::Logger::default()) - .service(web::scope("/chat").wrap(basic_auth_middleware.clone())) + // .wrap(basic_auth_middleware.clone()) // .service(extract_my_obj) // .service(index) - .service(routes::users::get_user) - .service(routes::users::add_user) - .service(routes::users::get_all_users) + // .service( + // web::scope("/api/users").wrap(basic_auth_middleware.clone()), + // ) + // .service(routes::users::get_user) + // .service(routes::users::get_all_users) + // .service(routes::users::add_user) + .service( + web::scope("/api/authzd") // endpoint requiring authentication + .wrap(basic_auth_middleware.clone()) + // .route("/get/{user_id}", web::to(routes::users::get_user)) + // .route("/get", web::to(routes::users::get_all_users)) + .service(routes::users::get_user) + .service(routes::users::get_all_users), + ) + .service(web::scope("/api/public")) // public endpoint - not implemented yet .service(routes::auth::login) .service(routes::auth::logout) .service(routes::auth::index) + .service(routes::users::add_user) .service(fs::Files::new("/", "./static")) }; HttpServer::new(app).bind(addr)?.run().await diff --git a/src/routes/auth.rs b/src/routes/auth.rs index 40e61eb..448030b 100644 --- a/src/routes/auth.rs +++ b/src/routes/auth.rs @@ -76,7 +76,8 @@ pub async fn index(id: Identity) -> String { ) } -fn validate_basic_auth( +/// basic auth middleware function +pub fn validate_basic_auth( credentials: BasicAuth, pool: &web::Data, ) -> Result { diff --git a/src/routes/chat.rs b/src/routes/chat.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/routes/chat.rs @@ -0,0 +1 @@ + diff --git a/src/routes/users.rs b/src/routes/users.rs index ce79894..1c06f61 100644 --- a/src/routes/users.rs +++ b/src/routes/users.rs @@ -5,18 +5,19 @@ use crate::models; use crate::types::DbPool; use actix_web::error::ResponseError; use std::rc::Rc; +use validator::Validate; /// Finds user by UID. -#[get("/api/authzd/users/get/{user_id}")] +#[get("/get/users/{user_id}")] pub async fn get_user( pool: web::Data, - user_uid: web::Path, + user_id: web::Path, ) -> Result { - let user_uid = user_uid.into_inner(); + let u_id = user_id.into_inner(); // use web::block to offload blocking Diesel code without blocking server thread let res = web::block(move || { let conn = pool.get()?; - actions::find_user_by_uid(user_uid, &conn) + actions::find_user_by_uid(u_id, &conn) }) .await .and_then(|maybe_user| { @@ -24,14 +25,14 @@ pub async fn get_user( Ok(HttpResponse::Ok().json(user)) } else { let res = HttpResponse::NotFound() - .body(format!("No user found with uid: {}", user_uid)); + .body(format!("No user found with uid: {}", u_id)); Ok(res) } }); res } -#[get("/api/authzd/users/get")] +#[get("/get/users")] pub async fn get_all_users( pool: web::Data, ) -> Result { @@ -68,14 +69,39 @@ pub async fn add_user( form: web::Json, ) -> Result { // use web::block to offload blocking Diesel code without blocking server thread - let user = web::block(move || { - let conn = pool.get()?; - actions::insert_new_user(Rc::new(form.0), &conn) - }) - .await - .and_then(|user| { - debug!("{:?}", user); - Ok(HttpResponse::Created().json(user)) - }); - user + let res = match form.0.validate() { + Ok(_) => web::block(move || { + let conn = pool.get()?; + actions::insert_new_user(Rc::new(form.0), &conn) + }) + .await + .and_then(|user| { + debug!("{:?}", user); + Ok(HttpResponse::Created().json(user)) + }), + + Err(e) => { + // let err = e.to_string(); + // web::block(move || { + // Err(crate::errors::DomainError::new_generic_error(err)) + // }) + // .await + + // let res2 = + // crate::errors::DomainError::new_generic_error(e.to_string()); + // Err(res2) + // let res2 = crate::errors::DomainError::GenericError { + // cause: e.to_string(), + // }; + // Err(res2) + let res = HttpResponse::BadRequest().body(e.to_string()); + // .json(models::ErrorModel::new( + // 40, + // "Error registering user due to validation errors", + // )); + Ok(res) + } + }; + + res } diff --git a/src/utils/auth.rs b/src/utils/auth.rs index 3e7749b..2903097 100644 --- a/src/utils/auth.rs +++ b/src/utils/auth.rs @@ -1,7 +1,13 @@ -use actix_web_httpauth::extractors::basic::BasicAuth; +use actix_web_httpauth::extractors::basic::{BasicAuth, Config}; // use actix_identity::Identity; -use actix_web::{dev::ServiceRequest, Error}; +use crate::{routes::validate_basic_auth, types::DbPool}; +use actix_http::ResponseError; +use actix_threadpool::BlockingError; + +use actix_web::{dev::ServiceRequest, web, Error}; + +// use Response; pub async fn validator( req: ServiceRequest, @@ -10,5 +16,35 @@ pub async fn validator( println!("{}", credentials.user_id()); println!("{:?}", credentials.password()); // verify credentials from db - Ok(req) + let credentials2 = credentials.clone(); + // let pool = req.app_data(); + let pool = req + .app_data::() + .expect("Error getting db") + // .get_ref() + .clone(); + // let _config = req + // .app_data::() + // .map(|data| data.get_ref().clone()) + // .unwrap_or_else(Default::default); + + let res = web::block(move || validate_basic_auth(credentials2, &pool)) + .await + .and_then(|valid| { + if valid { + debug!("Success"); + Ok(req) + } else { + debug!("Failure"); + Err(BlockingError::Error( + crate::errors::DomainError::new_password_error( + "Wrong password or account does not exist".to_string(), + ), + )) + // Err(AuthenticationError::from(config)) + // Ok(req) + } + }); + let res2: Result = res.map_err(|e| e.into()); + res2 }