(
credentials: &EmailAccountCredentials,
timeout: Duration,
)
| 566 | } |
| 567 | |
| 568 | fn connect_and_login( |
| 569 | credentials: &EmailAccountCredentials, |
| 570 | timeout: Duration, |
| 571 | ) -> Result<BlockingImapSession, EmailServiceError> { |
| 572 | let host = credentials.imap_host.trim(); |
| 573 | if host.is_empty() { |
| 574 | return Err(EmailServiceError::ClientSetup( |
| 575 | "IMAP host cannot be empty".to_string(), |
| 576 | )); |
| 577 | } |
| 578 | if credentials.imap_port == 0 { |
| 579 | return Err(EmailServiceError::ClientSetup( |
| 580 | "IMAP port must be greater than 0".to_string(), |
| 581 | )); |
| 582 | } |
| 583 | |
| 584 | let mut root_store = RootCertStore::empty(); |
| 585 | let native_certs = rustls_native_certs::load_native_certs(); |
| 586 | for cert in native_certs.certs { |
| 587 | root_store.add(cert).map_err(|e| { |
| 588 | EmailServiceError::ClientSetup(format!("failed to add native root certificate: {e}")) |
| 589 | })?; |
| 590 | } |
| 591 | if root_store.is_empty() { |
| 592 | if native_certs.errors.is_empty() { |
| 593 | return Err(EmailServiceError::ClientSetup( |
| 594 | "no native root certificates found".to_string(), |
| 595 | )); |
| 596 | } |
| 597 | return Err(EmailServiceError::ClientSetup(format!( |
| 598 | "failed to load native root certificates: {:?}", |
| 599 | native_certs.errors |
| 600 | ))); |
| 601 | } |
| 602 | |
| 603 | let client_config = ClientConfig::builder() |
| 604 | .with_root_certificates(root_store) |
| 605 | .with_no_client_auth(); |
| 606 | |
| 607 | let server_name = ServerName::try_from(host.to_string()) |
| 608 | .map_err(|_| EmailServiceError::ClientSetup(format!("invalid IMAP host '{host}'")))?; |
| 609 | |
| 610 | let socket = TcpStream::connect((host, credentials.imap_port)).map_err(|e| { |
| 611 | EmailServiceError::ClientSetup(format!( |
| 612 | "failed to connect to IMAP server {host}:{}: {e}", |
| 613 | credentials.imap_port |
| 614 | )) |
| 615 | })?; |
| 616 | socket |
| 617 | .set_read_timeout(Some(timeout)) |
| 618 | .map_err(|e| EmailServiceError::ClientSetup(format!("failed to set read timeout: {e}")))?; |
| 619 | socket |
| 620 | .set_write_timeout(Some(timeout)) |
| 621 | .map_err(|e| EmailServiceError::ClientSetup(format!("failed to set write timeout: {e}")))?; |
| 622 | |
| 623 | let connection = ClientConnection::new(Arc::new(client_config), server_name).map_err(|e| { |
| 624 | EmailServiceError::ClientSetup(format!("failed to initialize TLS client: {e}")) |
| 625 | })?; |
no test coverage detected