mirror of
https://github.com/mayanayza/netvisor.git
synced 2025-12-10 08:24:08 -06:00
Merge pull request #42 from mayanayza/feat/user-auth
fix: update session cookie security to allow for non-secure contexts
This commit is contained in:
@@ -223,6 +223,7 @@ The server supports the following configuration options:
|
||||
| Log Level | `--log-level` | `NETVISOR_LOG_LEVEL` | `info` | Logging verbosity (`trace`, `debug`, `info`, `warn`, `error`) |
|
||||
| Rust Log | `--rust-log` | `NETVISOR_RUST_LOG` | `""` | Low-level Rust framework logging |
|
||||
| Database URL | `--database-url` | `NETVISOR_DATABASE_URL` | `postgresql://postgres:password@localhost:5432/netvisor` | PostgreSQL connection string |
|
||||
| Use Secure Cookies | `--use-secure-session-cookies` | `NETVISOR_USE_SECURE_SESSION_COOKIES` | `false` | Set `true` when running behind HTTPS. Set `false` for HTTP/internal networks |
|
||||
|
||||
### UI Configuration
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ struct Cli {
|
||||
/// Override integrated daemon url
|
||||
#[arg(long)]
|
||||
integrated_daemon_url: Option<String>,
|
||||
|
||||
/// Use secure session cookies (if serving UI behind HTTPS)
|
||||
#[arg(long)]
|
||||
use_secure_session_cookies: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<Cli> for CliArgs {
|
||||
@@ -54,6 +58,7 @@ impl From<Cli> for CliArgs {
|
||||
rust_log: cli.rust_log,
|
||||
database_url: cli.database_url,
|
||||
integrated_daemon_url: cli.integrated_daemon_url,
|
||||
use_secure_session_cookies: cli.use_secure_session_cookies
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pub mod extractor;
|
||||
pub mod middleware;
|
||||
pub mod handlers;
|
||||
pub mod service;
|
||||
pub mod types;
|
||||
|
||||
@@ -17,6 +17,7 @@ pub struct CliArgs {
|
||||
pub rust_log: Option<String>,
|
||||
pub database_url: Option<String>,
|
||||
pub integrated_daemon_url: Option<String>,
|
||||
pub use_secure_session_cookies: Option<bool>
|
||||
}
|
||||
|
||||
/// Flattened server configuration struct
|
||||
@@ -40,6 +41,9 @@ pub struct ServerConfig {
|
||||
|
||||
/// URL for daemon running in same docker stack or in other local context
|
||||
pub integrated_daemon_url: Option<String>,
|
||||
|
||||
/// URL for daemon running in same docker stack or in other local context
|
||||
pub use_secure_session_cookies: bool,
|
||||
}
|
||||
|
||||
impl Default for ServerConfig {
|
||||
@@ -50,6 +54,7 @@ impl Default for ServerConfig {
|
||||
rust_log: "".to_string(),
|
||||
database_url: "postgresql://postgres:password@localhost:5432/netvisor".to_string(),
|
||||
web_external_path: None,
|
||||
use_secure_session_cookies: false,
|
||||
integrated_daemon_url: None,
|
||||
}
|
||||
}
|
||||
@@ -79,6 +84,9 @@ impl ServerConfig {
|
||||
if let Some(integrated_daemon_url) = cli_args.integrated_daemon_url {
|
||||
figment = figment.merge(("integrated_daemon_url", integrated_daemon_url));
|
||||
}
|
||||
if let Some(use_secure_session_cookies) = cli_args.use_secure_session_cookies {
|
||||
figment = figment.merge(("use_secure_session_cookies", use_secure_session_cookies));
|
||||
}
|
||||
|
||||
let config: ServerConfig = figment
|
||||
.extract()
|
||||
@@ -104,7 +112,7 @@ impl AppState {
|
||||
config: ServerConfig,
|
||||
discovery_manager: DiscoverySessionManager,
|
||||
) -> Result<Arc<Self>, Error> {
|
||||
let storage = StorageFactory::new(&config.database_url()).await?;
|
||||
let storage = StorageFactory::new(&config.database_url(), config.use_secure_session_cookies).await?;
|
||||
let services = ServiceFactory::new(&storage).await?;
|
||||
|
||||
Ok(Arc::new(Self {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::server::{
|
||||
auth::extractor::{AuthenticatedDaemon, AuthenticatedUser},
|
||||
auth::middleware::{AuthenticatedDaemon, AuthenticatedUser},
|
||||
config::AppState,
|
||||
daemons::types::{
|
||||
api::{DaemonRegistrationRequest, DaemonRegistrationResponse, GenerateKeyRequest},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::server::auth::extractor::AuthenticatedUser;
|
||||
use crate::server::auth::middleware::AuthenticatedUser;
|
||||
use crate::server::{
|
||||
config::AppState,
|
||||
groups::types::Group,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::server::auth::extractor::{AuthenticatedEntity, AuthenticatedUser};
|
||||
use crate::server::auth::middleware::{AuthenticatedEntity, AuthenticatedUser};
|
||||
use crate::server::{
|
||||
config::AppState,
|
||||
hosts::types::{api::HostWithServicesRequest, base::Host},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::server::{
|
||||
auth::extractor::AuthenticatedUser,
|
||||
auth::middleware::AuthenticatedUser,
|
||||
config::AppState,
|
||||
networks::types::Network,
|
||||
shared::types::api::{ApiError, ApiResponse, ApiResult},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::server::{
|
||||
auth::extractor::AuthenticatedUser,
|
||||
auth::middleware::AuthenticatedUser,
|
||||
config::AppState,
|
||||
services::types::base::Service,
|
||||
shared::types::api::{ApiResponse, ApiResult},
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct StorageFactory {
|
||||
}
|
||||
|
||||
pub async fn create_session_store(
|
||||
db_pool: Pool<Postgres>,
|
||||
db_pool: Pool<Postgres>, use_secure: bool
|
||||
) -> Result<SessionManagerLayer<PostgresStore>> {
|
||||
let session_store = PostgresStore::new(db_pool.clone());
|
||||
|
||||
@@ -35,17 +35,18 @@ pub async fn create_session_store(
|
||||
Ok(SessionManagerLayer::new(session_store)
|
||||
.with_expiry(Expiry::OnInactivity(time::Duration::days(30))) // 30 days
|
||||
.with_name("session_id")
|
||||
.with_secure(use_secure)
|
||||
.with_http_only(true)
|
||||
.with_same_site(tower_sessions::cookie::SameSite::Lax))
|
||||
}
|
||||
|
||||
impl StorageFactory {
|
||||
pub async fn new(database_url: &str) -> Result<Self> {
|
||||
pub async fn new(database_url: &str, use_secure_session_cookies: bool) -> Result<Self> {
|
||||
let pool = PgPool::connect(database_url).await?;
|
||||
|
||||
sqlx::migrate!("./migrations").run(&pool).await?;
|
||||
|
||||
let sessions = create_session_store(pool.clone()).await?;
|
||||
let sessions = create_session_store(pool.clone(), use_secure_session_cookies).await?;
|
||||
|
||||
Ok(Self {
|
||||
sessions,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::server::{
|
||||
auth::extractor::{AuthenticatedEntity, AuthenticatedUser},
|
||||
auth::middleware::{AuthenticatedEntity, AuthenticatedUser},
|
||||
config::AppState,
|
||||
shared::types::api::{ApiError, ApiResponse, ApiResult},
|
||||
subnets::types::base::Subnet,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::server::{
|
||||
auth::extractor::AuthenticatedUser,
|
||||
auth::middleware::AuthenticatedUser,
|
||||
config::AppState,
|
||||
shared::types::api::{ApiResponse, ApiResult},
|
||||
topology::types::api::TopologyRequestOptions,
|
||||
|
||||
@@ -59,7 +59,7 @@ pub async fn setup_test_db() -> (PgPool, String, ContainerAsync<GenericImage>) {
|
||||
pub async fn test_storage() -> (StorageFactory, ContainerAsync<GenericImage>) {
|
||||
let (pool, database_url, _container) = setup_test_db().await;
|
||||
pool.close().await;
|
||||
let factory = StorageFactory::new(&database_url).await.unwrap();
|
||||
let factory = StorageFactory::new(&database_url, false).await.unwrap();
|
||||
(factory, _container)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user