Files
EFC-DESK-V2/Utils/Util.cs
2026-02-09 10:55:45 -07:00

251 lines
8.1 KiB
C#

using EFCDesk.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Net.NetworkInformation;
namespace EFCDesk.Utils
{
public static class Util
{
private const string CLAVE_MAESTRA = "EFCDesk_MasterKey_2026";
public static bool StringsValidos(params string?[] valores)
{
return valores != null && valores.All(v => !string.IsNullOrWhiteSpace(v));
}
public static bool TieneValor<T>(T? valor)
{
return valor != null;
}
public static string ValorSeguro(string? valor, string valorPorDefecto = "")
{
return string.IsNullOrWhiteSpace(valor) ? valorPorDefecto : valor;
}
public static bool EsNumeroPositivo(int valor)
{
return valor > 0;
}
public static async Task<bool> Login(string usuario, string password)
{
Globales.configJson = ConfiguracionJSON.LoadFromJson();
bool Esvalido = StringsValidos(Globales.configJson.DominioExp);
if (!Esvalido)
{
MessageBox.Show("La configuración del dominio es inválida. Por favor, revise la configuración.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
Esvalido = StringsValidos(usuario, password);
if (!Esvalido)
{
MessageBox.Show("Debe ingresar Usuario y contraseña.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Globales.configJson.UsuarioExp = "";
Globales.configJson.PasswordExp = "";
Globales.configJson.SaveToJson();
return false;
}
using var apiClient = new ApiClient(timeout: TimeSpan.FromSeconds(600), maxRetries: 3, retryDelay: TimeSpan.FromSeconds(60));
// Crear diccionario con los datos
var loginData = new Dictionary<string, object>
{
{ "username", usuario},
{ "password", password}
};
string ApiPostLogin = Globales.configJson.DominioExp + apiClient.EndpointLoginToken();
string respuestaJson = await apiClient.PostJsonWithoutAuthAsync(url: ApiPostLogin, data: loginData);
if (!apiClient.IsJson(respuestaJson))
{
return false;
}
if (!apiClient.HasJsonData(respuestaJson))
{
return false;
}
if (JsonHelper.TryParse(respuestaJson, out var root))
{
var JsonData = JsonHelper.ToDictionary(root);
if (JsonData == null)
{
return false;
}
else
{
if (JsonData.ContainsKey("access"))
{
Globales.accesToken = JsonData["access"]?.ToString() ?? "";
}
if (JsonData.ContainsKey("refresh"))
{
Globales.refresToken = JsonData["refresh"]?.ToString() ?? "";
}
if (JsonData.ContainsKey("detail"))
{
string detalle = JsonData["detail"]?.ToString() ?? "Detalle desconocido";
MessageBox.Show(detalle, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
if (JsonData.ContainsKey("success"))
{
bool success = Convert.ToBoolean(JsonData["success"]);
if (!success)
{
string mensaje = JsonData["message"]?.ToString() ?? "Error desconocido";
MessageBox.Show(mensaje, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
if (string.IsNullOrEmpty(Globales.accesToken) || string.IsNullOrEmpty(Globales.refresToken))
{
MessageBox.Show("Error al obtener tokens de autenticación. Por favor, revise sus credenciales y la configuración del dominio.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
}
else
{
return false;
}
// Falta lógica para procesar la respuesta y devolver true/false según corresponda
// Por ahora, simplemente devolvemos true si la respuesta no es nula o vacía
return true;
}
private static string ObtenerMacAddress()
{
return NetworkInterface.GetAllNetworkInterfaces()
.Where(nic => nic.OperationalStatus == OperationalStatus.Up)
.Select(nic => nic.GetPhysicalAddress().ToString())
.FirstOrDefault() ?? "S0luc10n3501";
}
private static void DerivarClave(string password, string salt, out byte[] key, out byte[] iv)
{
key = Array.Empty<byte>();
iv = Array.Empty<byte>();
try
{
if (string.IsNullOrWhiteSpace(password))
throw new ArgumentException("Password inválido");
if (string.IsNullOrWhiteSpace(salt))
throw new ArgumentException("Salt inválido");
using var derivador = new Rfc2898DeriveBytes(
password,
Encoding.UTF8.GetBytes(salt),
100_000,
HashAlgorithmName.SHA256);
key = derivador.GetBytes(32); // AES-256
iv = derivador.GetBytes(16); // IV
}
catch (CryptographicException ex) { }
catch (Exception ex) { }
}
public static string Encriptar(string textoPlano, string? password = null, string? saltOpcional = null)
{
try
{
if (string.IsNullOrEmpty(textoPlano))
return string.Empty;
string salt = saltOpcional ?? ObtenerMacAddress();
string pass = password ?? CLAVE_MAESTRA;
DerivarClave(pass, salt, out var key, out var iv);
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
using var encryptor = aes.CreateEncryptor();
byte[] textoBytes = Encoding.UTF8.GetBytes(textoPlano);
byte[] textoEncriptado = encryptor.TransformFinalBlock(textoBytes, 0, textoBytes.Length);
return Convert.ToBase64String(textoEncriptado);
}
catch (CryptographicException ex)
{
return string.Empty;
}
catch (Exception ex)
{
return string.Empty;
}
}
public static string Desencriptar(string textoEncriptado, string? password = null, string? saltOpcional = null)
{
try
{
if (string.IsNullOrEmpty(textoEncriptado))
return string.Empty;
string salt = saltOpcional ?? ObtenerMacAddress();
string pass = password ?? CLAVE_MAESTRA;
DerivarClave(pass, salt, out var key, out var iv);
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
using var decryptor = aes.CreateDecryptor();
byte[] textoBytes = Convert.FromBase64String(textoEncriptado);
byte[] textoPlano = decryptor.TransformFinalBlock(textoBytes, 0, textoBytes.Length);
return Encoding.UTF8.GetString(textoPlano);
}
catch (FormatException ex)
{
return string.Empty;
}
catch (Exception ex)
{
return string.Empty;
}
}
}
}