Added basic auth

TODO need to improve error handling
This commit is contained in:
Rohan Sircar 2020-08-12 01:21:20 +05:30
parent 72a88761ff
commit 667728bb02
7 changed files with 105 additions and 36 deletions

2
.env
View File

@ -1,2 +1,2 @@
DATABASE_URL=test.db
BIND_ADDRESS=127.0.0.1:8080
BIND_ADDRESS=127.0.0.1:7800

View File

@ -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<Sqlite, (Text, Timestamp)> {
use crate::schema::users::dsl::*;
users
.select((name, created_at))

View File

@ -75,14 +75,6 @@ async fn extract_my_obj(item: web::Json<MyObj>) -> 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

View File

@ -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<DbPool>,
) -> Result<bool, errors::DomainError> {

1
src/routes/chat.rs Normal file
View File

@ -0,0 +1 @@

View File

@ -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<DbPool>,
user_uid: web::Path<i32>,
user_id: web::Path<i32>,
) -> Result<HttpResponse, impl ResponseError> {
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<DbPool>,
) -> Result<HttpResponse, impl ResponseError> {
@ -68,14 +69,39 @@ pub async fn add_user(
form: web::Json<models::NewUser>,
) -> Result<HttpResponse, impl ResponseError> {
// 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
}

View File

@ -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::<DbPool>()
.expect("Error getting db")
// .get_ref()
.clone();
// let _config = req
// .app_data::<Config>()
// .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<ServiceRequest, Error> = res.map_err(|e| e.into());
res2
}