Compare commits
	
		
			2 Commits
		
	
	
		
			01411f76c4
			...
			786f078e45
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 786f078e45 | ||
|   | 103c380098 | 
| @@ -35,3 +35,6 @@ uuid = { version = "1.0", features = ["v4", "wasm-bindgen"] } | |||||||
| # Environment variable handling | # Environment variable handling | ||||||
| dotenvy = "0.15" | dotenvy = "0.15" | ||||||
| base64 = "0.21" | base64 = "0.21" | ||||||
|  |  | ||||||
|  | [dev-dependencies] | ||||||
|  | tokio = { version = "1.0", features = ["macros", "rt"] } | ||||||
							
								
								
									
										108
									
								
								src/config.rs
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								src/config.rs
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use std::env; | use std::env; | ||||||
|  | use base64::prelude::*; | ||||||
|  |  | ||||||
| /// Configuration for CalDAV server connection and authentication. | /// Configuration for CalDAV server connection and authentication. | ||||||
| ///  | ///  | ||||||
| @@ -137,7 +138,7 @@ impl CalDAVConfig { | |||||||
|     /// ``` |     /// ``` | ||||||
|     pub fn get_basic_auth(&self) -> String { |     pub fn get_basic_auth(&self) -> String { | ||||||
|         let credentials = format!("{}:{}", self.username, self.password); |         let credentials = format!("{}:{}", self.username, self.password); | ||||||
|         base64::encode(&credentials) |         BASE64_STANDARD.encode(&credentials) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -163,7 +164,6 @@ pub enum ConfigError { | |||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use super::*; |     use super::*; | ||||||
|     use std::env; |  | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_basic_auth_encoding() { |     fn test_basic_auth_encoding() { | ||||||
| @@ -176,7 +176,109 @@ mod tests { | |||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         let auth = config.get_basic_auth(); |         let auth = config.get_basic_auth(); | ||||||
|         let expected = base64::encode("testuser:testpass"); |         let expected = BASE64_STANDARD.encode("testuser:testpass"); | ||||||
|         assert_eq!(auth, expected); |         assert_eq!(auth, expected); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Integration test that authenticates with the actual Baikal CalDAV server | ||||||
|  |     ///  | ||||||
|  |     /// This test requires a valid .env file with: | ||||||
|  |     /// - CALDAV_SERVER_URL | ||||||
|  |     /// - CALDAV_USERNAME   | ||||||
|  |     /// - CALDAV_PASSWORD | ||||||
|  |     ///  | ||||||
|  |     /// 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"); | ||||||
|  |  | ||||||
|  |         println!("Testing authentication to: {}", config.server_url); | ||||||
|  |  | ||||||
|  |         // Create HTTP client | ||||||
|  |         let client = reqwest::Client::new(); | ||||||
|  |  | ||||||
|  |         // Make a simple OPTIONS request to test authentication | ||||||
|  |         let response = client | ||||||
|  |             .request(reqwest::Method::OPTIONS, &config.server_url) | ||||||
|  |             .header("Authorization", format!("Basic {}", config.get_basic_auth())) | ||||||
|  |             .header("User-Agent", "calendar-app/0.1.0") | ||||||
|  |             .send() | ||||||
|  |             .await | ||||||
|  |             .expect("Failed to send request to CalDAV server"); | ||||||
|  |  | ||||||
|  |         println!("Response status: {}", response.status()); | ||||||
|  |         println!("Response headers: {:#?}", response.headers()); | ||||||
|  |  | ||||||
|  |         // Check if we got a successful response or at least not a 401 Unauthorized | ||||||
|  |         assert!( | ||||||
|  |             response.status().is_success() || response.status() != 401, | ||||||
|  |             "Authentication failed with status: {}. Check your credentials in .env", | ||||||
|  |             response.status() | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // For Baikal/CalDAV servers, we should see DAV headers | ||||||
|  |         assert!( | ||||||
|  |             response.headers().contains_key("dav") ||  | ||||||
|  |             response.headers().contains_key("DAV") || | ||||||
|  |             response.status().is_success(), | ||||||
|  |             "Server doesn't appear to be a CalDAV server - missing DAV headers" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         println!("✓ Authentication test passed!"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// Test making a PROPFIND request to discover calendars | ||||||
|  |     ///  | ||||||
|  |     /// This test requires a valid .env file and makes an actual CalDAV PROPFIND request | ||||||
|  |     ///  | ||||||
|  |     /// 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"); | ||||||
|  |  | ||||||
|  |         let client = reqwest::Client::new(); | ||||||
|  |  | ||||||
|  |         // CalDAV PROPFIND request to discover calendars | ||||||
|  |         let propfind_body = r#"<?xml version="1.0" encoding="utf-8" ?> | ||||||
|  | <d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav"> | ||||||
|  |     <d:prop> | ||||||
|  |         <d:resourcetype /> | ||||||
|  |         <d:displayname /> | ||||||
|  |         <c:calendar-description /> | ||||||
|  |         <c:supported-calendar-component-set /> | ||||||
|  |     </d:prop> | ||||||
|  | </d:propfind>"#; | ||||||
|  |  | ||||||
|  |         let response = client | ||||||
|  |             .request(reqwest::Method::from_bytes(b"PROPFIND").unwrap(), &config.server_url) | ||||||
|  |             .header("Authorization", format!("Basic {}", config.get_basic_auth())) | ||||||
|  |             .header("Content-Type", "application/xml") | ||||||
|  |             .header("Depth", "1") | ||||||
|  |             .header("User-Agent", "calendar-app/0.1.0") | ||||||
|  |             .body(propfind_body) | ||||||
|  |             .send() | ||||||
|  |             .await | ||||||
|  |             .expect("Failed to send PROPFIND request"); | ||||||
|  |  | ||||||
|  |         let status = response.status(); | ||||||
|  |         println!("PROPFIND Response status: {}", status); | ||||||
|  |          | ||||||
|  |         let body = response.text().await.expect("Failed to read response body"); | ||||||
|  |         println!("PROPFIND Response body: {}", body); | ||||||
|  |  | ||||||
|  |         // We should get a 207 Multi-Status for PROPFIND | ||||||
|  |         assert_eq!( | ||||||
|  |             status, | ||||||
|  |             reqwest::StatusCode::from_u16(207).unwrap(), | ||||||
|  |             "PROPFIND should return 207 Multi-Status" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // The response should contain XML with calendar information | ||||||
|  |         assert!(body.contains("calendar"), "Response should contain calendar information"); | ||||||
|  |  | ||||||
|  |         println!("✓ PROPFIND calendars test passed!"); | ||||||
|  |     } | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user