Added configuration file and loggign.
This commit is contained in:
+6
-2
@@ -1,5 +1,4 @@
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
pub mod data;
|
||||
pub mod company;
|
||||
pub mod user;
|
||||
@@ -10,13 +9,17 @@ pub mod opening_hours;
|
||||
macro_rules! perm_check {
|
||||
($check:ident) => {
|
||||
use crate::backend::user::$check;
|
||||
use crate::backend::user::logged_in_user;
|
||||
use actix_web::http::StatusCode;
|
||||
use leptos_actix::ResponseOptions;
|
||||
use log::warn;
|
||||
|
||||
if !$check().await {
|
||||
let response = expect_context::<ResponseOptions>();
|
||||
response.set_status(StatusCode::FORBIDDEN);
|
||||
|
||||
warn!("Permission denied for user: {}", logged_in_user().await.unwrap_or_default().login);
|
||||
|
||||
return Ok(ApiResponse::Error("Forbidden".to_string()))
|
||||
}
|
||||
}
|
||||
@@ -26,7 +29,6 @@ macro_rules! perm_check {
|
||||
macro_rules! user_check {
|
||||
($check:expr) => {
|
||||
use crate::perm_check;
|
||||
use crate::backend::user::logged_in_user;
|
||||
|
||||
perm_check!(is_logged_in);
|
||||
let user = logged_in_user().await.unwrap_or(User::default());
|
||||
@@ -35,6 +37,8 @@ macro_rules! user_check {
|
||||
let response = expect_context::<ResponseOptions>();
|
||||
response.set_status(StatusCode::FORBIDDEN);
|
||||
|
||||
warn!("Try to update not owned data. User: {}", user.login);
|
||||
|
||||
return Ok(ApiResponse::Error("You can change your own profile only".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -8,6 +8,7 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
use sqlx::{query_as, Error, PgPool, query};
|
||||
use actix_session::*;
|
||||
use leptos_actix::{extract, redirect};
|
||||
use log::{info, warn};
|
||||
|
||||
pub async fn has_admin_user(pool: &PgPool) -> Result<bool, Error> {
|
||||
let count: (i64,) = query_as(r#"SELECT COUNT(id) FROM "user" WHERE admin = $1"#)
|
||||
@@ -58,7 +59,7 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
}
|
||||
}}
|
||||
|
||||
#[server(Login, "/api")]
|
||||
#[server]
|
||||
pub async fn login(username: String, password: String) -> Result<ApiResponse<()>, ServerFnError> {
|
||||
use actix_session::*;
|
||||
use leptos_actix::extract;
|
||||
@@ -75,10 +76,13 @@ pub async fn login(username: String, password: String) -> Result<ApiResponse<()>
|
||||
})
|
||||
.await?;
|
||||
|
||||
info!("User {} logged in", username);
|
||||
|
||||
redirect("/admin");
|
||||
return Ok(ApiResponse::Data(()));
|
||||
}
|
||||
|
||||
warn!("Login failed for user {}", username);
|
||||
let response = expect_context::<ResponseOptions>();
|
||||
response.set_status(StatusCode::UNAUTHORIZED);
|
||||
|
||||
@@ -230,6 +234,8 @@ pub async fn create_user(user: UserProfile) -> Result<ApiResponse<()>, ServerFnE
|
||||
.execute(&pool)
|
||||
.await?;
|
||||
|
||||
info!("Created user {}", user.login());
|
||||
|
||||
Ok(ApiResponse::Data(()))
|
||||
}
|
||||
|
||||
@@ -259,5 +265,7 @@ pub async fn delete_user(id: i32) -> Result<ApiResponse<()>, ServerFnError> {
|
||||
.execute(&get_pool().await?)
|
||||
.await?;
|
||||
|
||||
info!("User deleted");
|
||||
|
||||
Ok(ApiResponse::Data(()))
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#[cfg(feature = "ssr")]
|
||||
use std::fs::read_to_string;
|
||||
#[cfg(feature = "ssr")]
|
||||
use std::net::SocketAddr;
|
||||
#[cfg(feature = "ssr")]
|
||||
use std::str::FromStr;
|
||||
#[cfg(feature = "ssr")]
|
||||
use serde::Deserialize;
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Network {
|
||||
bind_ip: String,
|
||||
port: u16
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
impl Network {
|
||||
pub fn bind_address(&self) -> SocketAddr {
|
||||
SocketAddr::from_str(format!("{}:{}", &self.bind_ip, self.port).as_str()).expect("Can't parse bind IP address")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Database {
|
||||
user: String,
|
||||
password: String,
|
||||
db_name: String,
|
||||
host: String,
|
||||
port: Option<u16>
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
impl Database {
|
||||
pub fn con_string(&self) -> String {
|
||||
format!("postgres://{}:{}@{}:{}/{}", self.user, self.password, self.host, self.port.unwrap_or(5432), self.db_name)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Configuration {
|
||||
network: Network,
|
||||
database: Database
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
impl Configuration {
|
||||
pub fn network(&self) -> &Network {
|
||||
&self.network
|
||||
}
|
||||
pub fn database(&self) -> &Database {
|
||||
&self.database
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub fn load_config(path: &str) -> Configuration {
|
||||
toml::from_str(read_to_string(path).expect("Can not open config file").as_str()).expect("Can not parse config file")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ mod pages;
|
||||
mod components;
|
||||
mod validator;
|
||||
pub mod error;
|
||||
pub mod config;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
|
||||
+25
-3
@@ -14,16 +14,38 @@ async fn main() -> std::io::Result<()> {
|
||||
use sqlx::migrate;
|
||||
use sqlx::postgres::PgPoolOptions;
|
||||
use rezervator::backend::auth_middleware::Authentication;
|
||||
use rezervator::config::load_config;
|
||||
use env_logger::Env;
|
||||
use std::env::args;
|
||||
use getopts::Options;
|
||||
use log::info;
|
||||
|
||||
let args: Vec<String> = args().collect();
|
||||
let mut opts = Options::new();
|
||||
opts.optopt("c", "config", "Path to config file. Default is ./config.toml", "");
|
||||
opts.optflag("h", "help", "Show help");
|
||||
let matches = opts.parse(&args[1..]).expect("Can't parse commandline");
|
||||
|
||||
if matches.opt_present("h") {
|
||||
println!("{}",opts.usage(format!("Usage: {} [options]",
|
||||
args.get(0).unwrap_or(&"".to_string())).as_str()));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let cfg_path = matches.opt_str("c").unwrap_or("config.toml".to_string());
|
||||
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||
info!("Starting server");
|
||||
|
||||
let conf = get_configuration(None).await.unwrap();
|
||||
let addr = conf.leptos_options.site_addr;
|
||||
let srv_conf = load_config(&cfg_path);
|
||||
// Generate the list of routes in your Leptos App
|
||||
let routes = generate_route_list(|| view! { <App/> });
|
||||
let key = Key::generate();
|
||||
|
||||
let pool = PgPoolOptions::new()
|
||||
.max_connections(10)
|
||||
.connect("postgres://pepa:mkoijn@localhost/rezervator").await.unwrap();
|
||||
.connect(&srv_conf.database().con_string()).await.unwrap();
|
||||
|
||||
migrate!().run(&pool).await.expect("could not run SQLx migrations");
|
||||
|
||||
@@ -47,7 +69,7 @@ async fn main() -> std::io::Result<()> {
|
||||
.service(Files::new("/", site_root))
|
||||
//.wrap(middleware::Compress::default())
|
||||
})
|
||||
.bind(&addr)?
|
||||
.bind(srv_conf.network().bind_address())?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user