feat: Implement initial backend structure with API, WebSocket, core models, services, and documentation, alongside dependency and gitignore updates.
This commit is contained in:
1 parent
f82191dd83
commit
7710be86a6
29 files changed
+3927
-1301
No files matched your search
@@ -0,0 +1,261 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use crate::services::system;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PermissionStatus {
|
||||
pub admin: bool,
|
||||
pub firewall_configured: bool,
|
||||
pub defender_exception: bool,
|
||||
pub network_ok: bool,
|
||||
pub issues: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct WindowsPermissions;
|
||||
|
||||
impl WindowsPermissions {
|
||||
/// Verifica se o processo está rodando com privilégios de administrador
|
||||
pub fn check_admin() -> bool {
|
||||
let ps_cmd = r#"[Security.Principal.WindowsPrincipal]::Current.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"#;
|
||||
match system::run_cmd("powershell", &["-NoProfile", "-Command", ps_cmd]) {
|
||||
Ok(output) => {
|
||||
let trimmed = output.trim().to_lowercase();
|
||||
trimmed == "true"
|
||||
}
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Verifica se uma regra de firewall já existe
|
||||
fn firewall_rule_exists(display_name: &str) -> bool {
|
||||
let ps_cmd = format!(
|
||||
r#"Get-NetFirewallRule -DisplayName '{}' -ErrorAction SilentlyContinue | Select-Object -First 1"#,
|
||||
display_name
|
||||
);
|
||||
match system::run_cmd("powershell", &["-NoProfile", "-Command", &ps_cmd]) {
|
||||
Ok(output) => !output.trim().is_empty(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Adiciona regra no firewall do Windows para uma porta específica
|
||||
pub fn request_firewall_rule(port: u16, name: &str) -> Result<(), String> {
|
||||
let display_name = format!("OllaHubBackend {}", name);
|
||||
|
||||
// Verificar se já existe
|
||||
if Self::firewall_rule_exists(&display_name) {
|
||||
system::info(&format!("Regra de firewall '{}' já existe", display_name));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Verificar se tem privilégios de admin
|
||||
if !Self::check_admin() {
|
||||
return Err(format!(
|
||||
"Privilégios de administrador necessários para adicionar regra de firewall na porta {}. Execute como Administrador.",
|
||||
port
|
||||
));
|
||||
}
|
||||
|
||||
// Criar regra de firewall
|
||||
let ps_cmd = format!(
|
||||
r#"New-NetFirewallRule -DisplayName '{}' -Direction Inbound -LocalPort {} -Protocol TCP -Action Allow -Profile Domain,Private,Public"#,
|
||||
display_name, port
|
||||
);
|
||||
|
||||
match system::run_cmd("powershell", &["-NoProfile", "-Command", &ps_cmd]) {
|
||||
Ok(_) => {
|
||||
system::info(&format!("Regra de firewall criada para porta {} ({})", port, name));
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(format!("Falha ao criar regra de firewall: {}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtém o caminho do executável atual
|
||||
fn get_executable_path() -> Result<PathBuf, String> {
|
||||
env::current_exe().map_err(|e| format!("Não foi possível obter caminho do executável: {}", e))
|
||||
}
|
||||
|
||||
/// Verifica se exceção já existe no Windows Defender
|
||||
fn defender_exception_exists(path: &str) -> bool {
|
||||
let ps_cmd = format!(
|
||||
r#"Get-MpPreference | Select-Object -ExpandProperty ExclusionPath | Where-Object {{ $_ -eq '{}' }}"#,
|
||||
path.replace('\\', "\\\\")
|
||||
);
|
||||
match system::run_cmd("powershell", &["-NoProfile", "-Command", &ps_cmd]) {
|
||||
Ok(output) => !output.trim().is_empty(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Adiciona exceção no Windows Defender para o executável
|
||||
pub fn request_defender_exception(exe_path: &str) -> Result<(), String> {
|
||||
// Verificar se já existe
|
||||
if Self::defender_exception_exists(exe_path) {
|
||||
system::info(&format!("Exceção do Windows Defender já existe para: {}", exe_path));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Verificar se tem privilégios de admin
|
||||
if !Self::check_admin() {
|
||||
return Err(format!(
|
||||
"Privilégios de administrador necessários para adicionar exceção no Windows Defender. Execute como Administrador."
|
||||
));
|
||||
}
|
||||
|
||||
// Adicionar exceção de caminho
|
||||
let ps_cmd = format!(
|
||||
r#"Add-MpPreference -ExclusionPath '{}'"#,
|
||||
exe_path.replace('\'', "''")
|
||||
);
|
||||
|
||||
match system::run_cmd("powershell", &["-NoProfile", "-Command", &ps_cmd]) {
|
||||
Ok(_) => {
|
||||
system::info(&format!("Exceção do Windows Defender adicionada para: {}", exe_path));
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(format!("Falha ao adicionar exceção no Windows Defender: {}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Verifica permissões de rede (básico)
|
||||
pub fn request_network_permissions() -> Result<(), String> {
|
||||
// Verificação básica: tentar criar um socket de teste
|
||||
// Se falhar, pode indicar problemas de permissão
|
||||
// Por enquanto, apenas retorna Ok se estiver no Windows
|
||||
if cfg!(target_os = "windows") {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Verificação de permissões de rede apenas disponível no Windows".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Configura todas as permissões necessárias
|
||||
pub fn setup_all_permissions() -> Result<PermissionStatus, String> {
|
||||
system::info("Verificando e configurando permissões do Windows...");
|
||||
|
||||
let mut status = PermissionStatus {
|
||||
admin: Self::check_admin(),
|
||||
firewall_configured: false,
|
||||
defender_exception: false,
|
||||
network_ok: false,
|
||||
issues: Vec::new(),
|
||||
};
|
||||
|
||||
// Log status de admin
|
||||
system::info("[1/4] Verificando privilégios de administrador...");
|
||||
if status.admin {
|
||||
system::info(" ✓ Executando com privilégios de administrador");
|
||||
} else {
|
||||
system::warn(" ⚠ Não está executando como administrador. Algumas configurações podem falhar.");
|
||||
status.issues.push("Execução sem privilégios de administrador".to_string());
|
||||
}
|
||||
|
||||
// Configurar firewall para porta 8080 (API)
|
||||
system::info("[2/4] Configurando regras de firewall...");
|
||||
system::info(" → Porta 8080 (API HTTP)...");
|
||||
match Self::request_firewall_rule(8080, "API") {
|
||||
Ok(_) => {
|
||||
status.firewall_configured = true;
|
||||
system::info(" ✓ Regra de firewall criada para porta 8080");
|
||||
}
|
||||
Err(e) => {
|
||||
status.issues.push(format!("Firewall porta 8080: {}", e));
|
||||
system::warn(&format!(" ✗ Falha: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
// Configurar firewall para porta 11434 (Ollama)
|
||||
system::info(" → Porta 11434 (Ollama)...");
|
||||
match Self::request_firewall_rule(11434, "Ollama") {
|
||||
Ok(_) => {
|
||||
// Se a porta 8080 foi configurada, manter firewall_configured como true
|
||||
if !status.firewall_configured {
|
||||
status.firewall_configured = true;
|
||||
}
|
||||
system::info(" ✓ Regra de firewall criada para porta 11434");
|
||||
}
|
||||
Err(e) => {
|
||||
status.issues.push(format!("Firewall porta 11434: {}", e));
|
||||
system::warn(&format!(" ✗ Falha: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
// Configurar exceção no Windows Defender
|
||||
system::info("[3/4] Configurando exceção no Windows Defender...");
|
||||
match Self::get_executable_path() {
|
||||
Ok(exe_path) => {
|
||||
let exe_str = exe_path.to_string_lossy().to_string();
|
||||
system::info(&format!(" → Executável: {}", exe_str));
|
||||
match Self::request_defender_exception(&exe_str) {
|
||||
Ok(_) => {
|
||||
status.defender_exception = true;
|
||||
system::info(" ✓ Exceção adicionada no Windows Defender");
|
||||
}
|
||||
Err(e) => {
|
||||
status.issues.push(format!("Windows Defender: {}", e));
|
||||
system::warn(&format!(" ✗ Falha: {}", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
status.issues.push(format!("Não foi possível obter caminho do executável: {}", e));
|
||||
system::warn(&format!(" ✗ Não foi possível configurar exceção no Windows Defender: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar permissões de rede
|
||||
system::info("[4/4] Verificando permissões de rede...");
|
||||
match Self::request_network_permissions() {
|
||||
Ok(_) => {
|
||||
status.network_ok = true;
|
||||
system::info(" ✓ Permissões de rede OK");
|
||||
}
|
||||
Err(e) => {
|
||||
status.issues.push(format!("Permissões de rede: {}", e));
|
||||
system::warn(&format!(" ✗ Falha: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
// Resumo final
|
||||
system::info("========================================");
|
||||
if status.issues.is_empty() {
|
||||
system::info("✓ Todas as permissões foram configuradas com sucesso!");
|
||||
} else {
|
||||
system::warn(&format!("⚠ {} problema(s) encontrado(s) durante configuração de permissões", status.issues.len()));
|
||||
system::info("");
|
||||
system::info("📋 Instruções manuais para resolver problemas:");
|
||||
system::info("");
|
||||
if !status.admin {
|
||||
system::info(" 1. PRIVILÉGIOS DE ADMINISTRADOR:");
|
||||
system::info(" → Clique com botão direito no executável");
|
||||
system::info(" → Selecione 'Executar como administrador'");
|
||||
system::info("");
|
||||
}
|
||||
if !status.firewall_configured {
|
||||
system::info(" 2. REGRAS DE FIREWALL:");
|
||||
system::info(" → Abra: Painel de Controle > Firewall do Windows > Configurações avançadas");
|
||||
system::info(" → Clique em 'Regras de entrada' > 'Nova regra...'");
|
||||
system::info(" → Tipo: Porta > TCP > Portas específicas: 8080, 11434");
|
||||
system::info(" → Ação: Permitir a conexão");
|
||||
system::info(" → Nome: 'OllaHubBackend API' e 'OllaHubBackend Ollama'");
|
||||
system::info("");
|
||||
}
|
||||
if !status.defender_exception {
|
||||
system::info(" 3. EXCEÇÃO NO WINDOWS DEFENDER:");
|
||||
if let Ok(exe_path) = Self::get_executable_path() {
|
||||
system::info(" → Abra: Windows Security > Virus & threat protection");
|
||||
system::info(" → Clique em 'Manage settings' (Gerenciar configurações)");
|
||||
system::info(" → Role até 'Exclusions' > 'Add or remove exclusions'");
|
||||
system::info(" → Adicione exceção de 'File' com o caminho:");
|
||||
system::info(&format!(" {}", exe_path.to_string_lossy()));
|
||||
}
|
||||
system::info("");
|
||||
}
|
||||
}
|
||||
system::info("========================================");
|
||||
|
||||
Ok(status)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user