diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..a18472d --- /dev/null +++ b/.env.sample @@ -0,0 +1 @@ +DATABASE_URL=postgresql://server:5432/database?user=user&password=password&connectTimeout=30¤tSchema=storage; \ No newline at end of file diff --git a/src/consts.rs b/src/consts.rs index 5332850..3f33246 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,4 +1,6 @@ use std::cell::OnceCell; +use std::env; +use std::sync::OnceLock; use std::time::Duration; use rocket::data::ByteUnit; use rocket::serde::Serialize; @@ -14,7 +16,6 @@ pub const SESSION_LIFETIME_SECONDS: u64 = 3600 * 24 * 14; // 14 days pub const SESSION_COOKIE_NAME: &'static str = "storage-session"; - #[derive(Serialize)] pub struct FileConstants<'a> { pub display_options: &'a[&'a str], @@ -25,3 +26,10 @@ pub const FILE_CONSTANTS: FileConstants = FileConstants { sort_keys: &["name", "last_modified", "size"], }; + +/// Disables CSRF & password verification for login +/// Used for development due to no session persistence +pub static DISABLE_LOGIN_CHECK: OnceLock = OnceLock::new(); +pub fn init_statics() { + DISABLE_LOGIN_CHECK.set(env::var("DANGER_DISABLE_LOGIN_CHECKS").is_ok()).unwrap(); +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9ae8367..d4475d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ use crate::managers::repos::RepoManager; use crate::objs::library::Library; use crate::util::{setup_logger, JsonErrorResponse, ResponseError}; use routes::api; -use crate::consts::{SESSION_COOKIE_NAME, SESSION_LIFETIME_SECONDS}; +use crate::consts::{init_statics, SESSION_COOKIE_NAME, SESSION_LIFETIME_SECONDS}; use crate::models::user::UserModel; use crate::routes::ui; @@ -70,6 +70,7 @@ pub struct GlobalMetadata { async fn rocket() -> _ { setup_logger(); dotenvy::dotenv().ok(); + init_statics(); trace!("trace"); debug!("debug"); diff --git a/src/models/user.rs b/src/models/user.rs index c582e0a..b9fd904 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -10,7 +10,7 @@ use rocket::response::Responder; use rocket::serde::Serialize; use rocket::serde::uuid::Uuid; use sqlx::{query_as, FromRow}; -use crate::consts::ENCRYPTION_ROUNDS; +use crate::consts::{DISABLE_LOGIN_CHECK, ENCRYPTION_ROUNDS}; use crate::{LoginSessionData, SessionData, DB}; use crate::models::repo::RepoModel; use crate::util::JsonErrorResponse; @@ -124,7 +124,7 @@ pub async fn validate_user(pool: &DB, email_or_usrname: &str, password: &str) -> return Err(UserAuthError::UserNotFound); }; if let Some(db_password) = user.password { - if bcrypt::verify(password, &db_password).map_err(|e| UserAuthError::EncryptionError(e))? { + if !DISABLE_LOGIN_CHECK.get().unwrap() || bcrypt::verify(password, &db_password).map_err(|e| UserAuthError::EncryptionError(e))? { return Ok(UserModel { id: user.id, email: user.email, diff --git a/src/routes/ui/auth/login.rs b/src/routes/ui/auth/login.rs index a57e525..045a1f0 100644 --- a/src/routes/ui/auth/login.rs +++ b/src/routes/ui/auth/login.rs @@ -6,6 +6,7 @@ use rocket::http::{Header, Status}; use rocket_dyn_templates::{context, Template}; use rocket_session_store::Session; use crate::{GlobalMetadata, LoginSessionData, SessionData, DB}; +use crate::consts::DISABLE_LOGIN_CHECK; use crate::models::user::validate_user_form; use crate::util::{set_csrf, validate_csrf_form}; @@ -60,7 +61,9 @@ pub async fn handler( return_to: Option, ) -> Result { trace!("handler"); - validate_csrf_form(&mut form.context, &session).await; + if !DISABLE_LOGIN_CHECK.get().unwrap() { + validate_csrf_form(&mut form.context, &session).await; + } let user = validate_user_form(&mut form.context, &pool).await; trace!("check form"); if form.context.status() == Status::Ok {