tftsr-devops_investigation/src-tauri/src/lib.rs
Shaun Arman 32d83df3cf
Some checks failed
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
feat: add multi-mode authentication for integrations (v0.2.10)
Implement three authentication methods for Confluence, ServiceNow, and Azure DevOps:

1. **OAuth2** - Traditional OAuth flow for enterprise SSO environments
2. **Embedded Browser** - Webview-based login that captures session cookies/tokens
   - Solves VPN constraints: users authenticate off-VPN via web UI
   - Extracted credentials work on-VPN for API calls
   - Based on confluence-publisher agent pattern
3. **Manual Token** - Direct API token/PAT input as fallback

**Changes:**
- Add webview_auth.rs module for embedded browser authentication
- Implement authenticate_with_webview and extract_cookies_from_webview commands
- Implement save_manual_token command with validation
- Add AuthMethod enum to support all three modes
- Add RadioGroup UI component for mode selection
- Complete rewrite of Integrations settings page with mode-specific UI
- Add secondary button variant for UI consistency

**VPN-friendly design:**
Users can authenticate via webview when off-VPN (web UI accessible), then use extracted cookies for API calls when on-VPN (API requires VPN). Addresses enterprise SSO limitations where OAuth app registration is blocked.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 17:26:09 -05:00

149 lines
5.0 KiB
Rust

pub mod ai;
pub mod audit;
pub mod commands;
pub mod db;
pub mod docs;
pub mod integrations;
pub mod ollama;
pub mod pii;
pub mod state;
use state::AppState;
use std::sync::{Arc, Mutex};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
// Initialize tracing subscriber for structured logging
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.init();
tracing::info!("Starting TFTSR application");
// Determine data directory
let data_dir = dirs_data_dir();
// Initialize database
let conn = db::connection::init_db(&data_dir).expect("Failed to initialize database");
tracing::info!("Database initialized at {:?}", data_dir);
let app_state = AppState {
db: Arc::new(Mutex::new(conn)),
settings: Arc::new(Mutex::new(state::AppSettings::default())),
app_data_dir: data_dir.clone(),
};
tauri::Builder::default()
.plugin(
tauri_plugin_stronghold::Builder::new(|password| {
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
hasher.update(password);
hasher.update(b"tftsr-stronghold-salt-v1");
hasher.finalize().to_vec()
})
.build(),
)
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_http::init())
.manage(app_state)
.invoke_handler(tauri::generate_handler![
// DB / Issue CRUD
commands::db::create_issue,
commands::db::get_issue,
commands::db::update_issue,
commands::db::delete_issue,
commands::db::list_issues,
commands::db::search_issues,
commands::db::get_issue_messages,
commands::db::add_five_why,
commands::db::update_five_why,
commands::db::add_timeline_event,
// Analysis / PII
commands::analysis::upload_log_file,
commands::analysis::detect_pii,
commands::analysis::apply_redactions,
// AI
commands::ai::analyze_logs,
commands::ai::chat_message,
commands::ai::test_provider_connection,
commands::ai::list_providers,
// Docs
commands::docs::generate_rca,
commands::docs::generate_postmortem,
commands::docs::update_document,
commands::docs::export_document,
// Integrations
commands::integrations::test_confluence_connection,
commands::integrations::publish_to_confluence,
commands::integrations::test_servicenow_connection,
commands::integrations::create_servicenow_incident,
commands::integrations::test_azuredevops_connection,
commands::integrations::create_azuredevops_workitem,
commands::integrations::initiate_oauth,
commands::integrations::handle_oauth_callback,
commands::integrations::authenticate_with_webview,
commands::integrations::extract_cookies_from_webview,
commands::integrations::save_manual_token,
// System / Settings
commands::system::check_ollama_installed,
commands::system::get_ollama_install_guide,
commands::system::list_ollama_models,
commands::system::pull_ollama_model,
commands::system::delete_ollama_model,
commands::system::detect_hardware,
commands::system::recommend_models,
commands::system::get_settings,
commands::system::update_settings,
commands::system::get_audit_log,
])
.run(tauri::generate_context!())
.expect("Error running TFTSR application");
}
/// Determine the application data directory.
fn dirs_data_dir() -> std::path::PathBuf {
if let Ok(dir) = std::env::var("TFTSR_DATA_DIR") {
return std::path::PathBuf::from(dir);
}
// Use platform-appropriate data directory
#[cfg(target_os = "linux")]
{
if let Ok(xdg) = std::env::var("XDG_DATA_HOME") {
return std::path::PathBuf::from(xdg).join("tftsr");
}
if let Ok(home) = std::env::var("HOME") {
return std::path::PathBuf::from(home)
.join(".local")
.join("share")
.join("tftsr");
}
}
#[cfg(target_os = "macos")]
{
if let Ok(home) = std::env::var("HOME") {
return std::path::PathBuf::from(home)
.join("Library")
.join("Application Support")
.join("tftsr");
}
}
#[cfg(target_os = "windows")]
{
if let Ok(appdata) = std::env::var("APPDATA") {
return std::path::PathBuf::from(appdata).join("tftsr");
}
}
// Fallback
std::path::PathBuf::from("./tftsr-data")
}