Clean up obsolete CalDAV environment variables
Some checks failed
Build and Push Docker Image / docker (push) Failing after 2s
Some checks failed
Build and Push Docker Image / docker (push) Failing after 2s
## Removed Obsolete Environment Variables: - `CALDAV_SERVER_URL` - provided by user login - `CALDAV_USERNAME` - provided by user login - `CALDAV_PASSWORD` - provided by user login - `CALDAV_TASKS_PATH` - not used in any features ## Kept with Intelligent Discovery: - `CALDAV_CALENDAR_PATH` - optional override, defaults to smart discovery ## Changes: ### Backend - Remove `CalDAVConfig::from_env()` method (not used in main app) - Add `CalDAVConfig::new()` constructor with credentials - Remove `tasks_path` field from CalDAVConfig - Update auth service to use new constructor - Update tests to use hardcoded test values instead of env vars - Update debug tools to use test credentials ### Frontend - Remove unused `config.rs` file entirely (frontend uses backend API) ## Current Authentication Flow: 1. User provides CalDAV credentials via login API 2. Backend creates CalDAVConfig dynamically from login request 3. Backend tests authentication via calendar discovery 4. Optional `CALDAV_CALENDAR_PATH` env var can override discovery 5. No environment variables required for normal operation This simplifies deployment - users only need to provide CalDAV credentials through the web interface, no server-side configuration required. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -31,13 +31,11 @@ impl AuthService {
|
||||
println!("✅ Input validation passed");
|
||||
|
||||
// Create CalDAV config with provided credentials
|
||||
let caldav_config = CalDAVConfig {
|
||||
server_url: request.server_url.clone(),
|
||||
username: request.username.clone(),
|
||||
password: request.password.clone(),
|
||||
calendar_path: None,
|
||||
tasks_path: None,
|
||||
};
|
||||
let caldav_config = CalDAVConfig::new(
|
||||
request.server_url.clone(),
|
||||
request.username.clone(),
|
||||
request.password.clone()
|
||||
);
|
||||
println!("📝 Created CalDAV config");
|
||||
|
||||
// Test authentication against CalDAV server
|
||||
@@ -74,13 +72,11 @@ impl AuthService {
|
||||
pub fn caldav_config_from_token(&self, token: &str, password: &str) -> Result<CalDAVConfig, ApiError> {
|
||||
let claims = self.verify_token(token)?;
|
||||
|
||||
Ok(CalDAVConfig {
|
||||
server_url: claims.server_url,
|
||||
username: claims.username,
|
||||
password: password.to_string(),
|
||||
calendar_path: None,
|
||||
tasks_path: None,
|
||||
})
|
||||
Ok(CalDAVConfig::new(
|
||||
claims.server_url,
|
||||
claims.username,
|
||||
password.to_string()
|
||||
))
|
||||
}
|
||||
|
||||
fn validate_login(&self, request: &CalDAVLoginRequest) -> Result<(), ApiError> {
|
||||
|
||||
@@ -17,14 +17,16 @@ use base64::prelude::*;
|
||||
///
|
||||
/// ```rust
|
||||
/// # use calendar_backend::config::CalDAVConfig;
|
||||
/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// // Load configuration from environment variables
|
||||
/// let config = CalDAVConfig::from_env()?;
|
||||
/// let config = CalDAVConfig {
|
||||
/// server_url: "https://caldav.example.com".to_string(),
|
||||
/// username: "user@example.com".to_string(),
|
||||
/// password: "password".to_string(),
|
||||
/// calendar_path: None,
|
||||
/// tasks_path: None,
|
||||
/// };
|
||||
///
|
||||
/// // Use the configuration for HTTP requests
|
||||
/// let auth_header = format!("Basic {}", config.get_basic_auth());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CalDAVConfig {
|
||||
@@ -41,74 +43,37 @@ pub struct CalDAVConfig {
|
||||
|
||||
/// Optional path to the calendar collection on the server
|
||||
///
|
||||
/// If not provided, the client will need to discover available calendars
|
||||
/// If not provided, the client will discover available calendars
|
||||
/// through CalDAV PROPFIND requests
|
||||
pub calendar_path: Option<String>,
|
||||
|
||||
/// Optional path to the tasks/todo collection on the server
|
||||
///
|
||||
/// Some CalDAV servers store tasks separately from calendar events
|
||||
pub tasks_path: Option<String>,
|
||||
}
|
||||
|
||||
impl CalDAVConfig {
|
||||
/// Creates a new CalDAVConfig by loading values from environment variables.
|
||||
/// Creates a new CalDAVConfig with the given credentials.
|
||||
///
|
||||
/// This method will attempt to load a `.env` file from the current directory
|
||||
/// and then read the following required environment variables:
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `CALDAV_SERVER_URL`: The CalDAV server base URL
|
||||
/// - `CALDAV_USERNAME`: Username for authentication
|
||||
/// - `CALDAV_PASSWORD`: Password for authentication
|
||||
///
|
||||
/// Optional environment variables:
|
||||
///
|
||||
/// - `CALDAV_CALENDAR_PATH`: Path to calendar collection
|
||||
/// - `CALDAV_TASKS_PATH`: Path to tasks collection
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns `ConfigError::MissingVar` if any required environment variable
|
||||
/// is not set or cannot be read.
|
||||
/// * `server_url` - The base URL of the CalDAV server
|
||||
/// * `username` - Username for authentication
|
||||
/// * `password` - Password for authentication
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use calendar_backend::config::CalDAVConfig;
|
||||
///
|
||||
/// match CalDAVConfig::from_env() {
|
||||
/// Ok(config) => {
|
||||
/// println!("Loaded config for server: {}", config.server_url);
|
||||
/// }
|
||||
/// Err(e) => {
|
||||
/// eprintln!("Failed to load config: {}", e);
|
||||
/// }
|
||||
/// }
|
||||
/// let config = CalDAVConfig::new(
|
||||
/// "https://caldav.example.com".to_string(),
|
||||
/// "user@example.com".to_string(),
|
||||
/// "password".to_string()
|
||||
/// );
|
||||
/// ```
|
||||
pub fn from_env() -> Result<Self, ConfigError> {
|
||||
// Attempt to load .env file, but don't fail if it doesn't exist
|
||||
dotenvy::dotenv().ok();
|
||||
|
||||
let server_url = env::var("CALDAV_SERVER_URL")
|
||||
.map_err(|_| ConfigError::MissingVar("CALDAV_SERVER_URL".to_string()))?;
|
||||
|
||||
let username = env::var("CALDAV_USERNAME")
|
||||
.map_err(|_| ConfigError::MissingVar("CALDAV_USERNAME".to_string()))?;
|
||||
|
||||
let password = env::var("CALDAV_PASSWORD")
|
||||
.map_err(|_| ConfigError::MissingVar("CALDAV_PASSWORD".to_string()))?;
|
||||
|
||||
// Optional paths - it's fine if these are not set
|
||||
let calendar_path = env::var("CALDAV_CALENDAR_PATH").ok();
|
||||
let tasks_path = env::var("CALDAV_TASKS_PATH").ok();
|
||||
|
||||
Ok(CalDAVConfig {
|
||||
pub fn new(server_url: String, username: String, password: String) -> Self {
|
||||
Self {
|
||||
server_url,
|
||||
username,
|
||||
password,
|
||||
calendar_path,
|
||||
tasks_path,
|
||||
})
|
||||
calendar_path: env::var("CALDAV_CALENDAR_PATH").ok(), // Optional override from env
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a Base64-encoded string for HTTP Basic Authentication.
|
||||
@@ -192,9 +157,12 @@ mod tests {
|
||||
/// Run with: `cargo test test_baikal_auth`
|
||||
#[tokio::test]
|
||||
async fn test_baikal_auth() {
|
||||
// Load config from .env
|
||||
let config = CalDAVConfig::from_env()
|
||||
.expect("Failed to load CalDAV config from environment");
|
||||
// Use test config - update these values to test with real server
|
||||
let config = CalDAVConfig::new(
|
||||
"https://example.com".to_string(),
|
||||
"test_user".to_string(),
|
||||
"test_password".to_string()
|
||||
);
|
||||
|
||||
println!("Testing authentication to: {}", config.server_url);
|
||||
|
||||
@@ -238,8 +206,12 @@ mod tests {
|
||||
/// Run with: `cargo test test_propfind_calendars`
|
||||
#[tokio::test]
|
||||
async fn test_propfind_calendars() {
|
||||
let config = CalDAVConfig::from_env()
|
||||
.expect("Failed to load CalDAV config from environment");
|
||||
// Use test config - update these values to test with real server
|
||||
let config = CalDAVConfig::new(
|
||||
"https://example.com".to_string(),
|
||||
"test_user".to_string(),
|
||||
"test_password".to_string()
|
||||
);
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
|
||||
@@ -2,7 +2,12 @@ use crate::calendar::CalDAVClient;
|
||||
use crate::config::CalDAVConfig;
|
||||
|
||||
pub async fn debug_caldav_fetch() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = CalDAVConfig::from_env()?;
|
||||
// Use debug/test configuration
|
||||
let config = CalDAVConfig::new(
|
||||
"https://example.com".to_string(),
|
||||
"debug_user".to_string(),
|
||||
"debug_password".to_string()
|
||||
);
|
||||
let client = CalDAVClient::new(config);
|
||||
|
||||
println!("=== DEBUG: CalDAV Fetch ===");
|
||||
|
||||
@@ -52,13 +52,11 @@ pub async fn login(
|
||||
println!("📝 Created CalDAV config");
|
||||
|
||||
// First verify the credentials are valid by attempting to discover calendars
|
||||
let config = CalDAVConfig {
|
||||
server_url: request.server_url.clone(),
|
||||
username: request.username.clone(),
|
||||
password: request.password.clone(),
|
||||
calendar_path: None,
|
||||
tasks_path: None,
|
||||
};
|
||||
let config = CalDAVConfig::new(
|
||||
request.server_url.clone(),
|
||||
request.username.clone(),
|
||||
request.password.clone()
|
||||
);
|
||||
let client = CalDAVClient::new(config);
|
||||
client.discover_calendars()
|
||||
.await
|
||||
|
||||
@@ -72,9 +72,9 @@ mod test_utils {
|
||||
|
||||
pub async fn login(&self) -> String {
|
||||
let login_payload = json!({
|
||||
"username": std::env::var("CALDAV_USERNAME").unwrap_or("test".to_string()),
|
||||
"password": std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string()),
|
||||
"server_url": std::env::var("CALDAV_SERVER_URL").unwrap_or("https://example.com".to_string())
|
||||
"username": "test".to_string(),
|
||||
"password": "test".to_string(),
|
||||
"server_url": "https://example.com".to_string()
|
||||
});
|
||||
|
||||
let response = self.client
|
||||
@@ -134,12 +134,10 @@ mod tests {
|
||||
async fn test_auth_login() {
|
||||
let server = TestServer::start().await;
|
||||
|
||||
// Load credentials from .env
|
||||
dotenvy::dotenv().ok();
|
||||
let username = std::env::var("CALDAV_USERNAME").unwrap_or("test".to_string());
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
|
||||
let server_url = std::env::var("CALDAV_SERVER_URL").unwrap_or("https://example.com".to_string());
|
||||
// Use test credentials
|
||||
let username = "test".to_string();
|
||||
let password = "test".to_string();
|
||||
let server_url = "https://example.com".to_string();
|
||||
|
||||
let login_payload = json!({
|
||||
"username": username,
|
||||
@@ -196,7 +194,7 @@ mod tests {
|
||||
|
||||
// Load password from env for CalDAV requests
|
||||
dotenvy::dotenv().ok();
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
let password = "test".to_string();
|
||||
|
||||
let response = server.client
|
||||
.get(&format!("{}/api/user/info", server.base_url))
|
||||
@@ -226,7 +224,7 @@ mod tests {
|
||||
|
||||
// Load password from env for CalDAV requests
|
||||
dotenvy::dotenv().ok();
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
let password = "test".to_string();
|
||||
|
||||
let response = server.client
|
||||
.get(&format!("{}/api/calendar/events?year=2024&month=12", server.base_url))
|
||||
@@ -254,7 +252,7 @@ mod tests {
|
||||
|
||||
// Load password from env for CalDAV requests
|
||||
dotenvy::dotenv().ok();
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
let password = "test".to_string();
|
||||
|
||||
let create_payload = json!({
|
||||
"title": "Integration Test Event",
|
||||
@@ -308,7 +306,7 @@ mod tests {
|
||||
|
||||
// Load password from env for CalDAV requests
|
||||
dotenvy::dotenv().ok();
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
let password = "test".to_string();
|
||||
|
||||
// Use a dummy UID for testing - this will likely return 404 but we're testing the endpoint structure
|
||||
let test_uid = "test-event-uid";
|
||||
@@ -373,7 +371,7 @@ mod tests {
|
||||
|
||||
// Load password from env for CalDAV requests
|
||||
dotenvy::dotenv().ok();
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
let password = "test".to_string();
|
||||
|
||||
let create_payload = json!({
|
||||
"title": "Integration Test Series",
|
||||
@@ -431,7 +429,7 @@ mod tests {
|
||||
|
||||
// Load password from env for CalDAV requests
|
||||
dotenvy::dotenv().ok();
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
let password = "test".to_string();
|
||||
|
||||
let update_payload = json!({
|
||||
"series_uid": "test-series-uid",
|
||||
@@ -493,7 +491,7 @@ mod tests {
|
||||
|
||||
// Load password from env for CalDAV requests
|
||||
dotenvy::dotenv().ok();
|
||||
let password = std::env::var("CALDAV_PASSWORD").unwrap_or("test".to_string());
|
||||
let password = "test".to_string();
|
||||
|
||||
let delete_payload = json!({
|
||||
"series_uid": "test-series-to-delete",
|
||||
|
||||
Reference in New Issue
Block a user