// Probe LECTURE SEULE ciblé : reproduit EXACTEMENT le mécanisme de connexion de l'API // (BusinessOleDbConnection -> HfSqlOleDbConnectionFactory -> BuildExtendedPropertiesFromFilePasswords) // pour tester l'accès aux tables Client, Lieu, ParametreMetier sur BATIK_TEST. // // Aucune écriture. Aucun password affiché. Aucun hash/dérivation. // Les seules valeurs utilisées sont celles de config/hfsql-test.local.json (Hfsql.FilePasswords). using System.Data.Common; using System.Reflection; using Microsoft.Extensions.Configuration; using Omika.Data.Configuration; using Omika.Data.Connection; using Omika.Data.HfSql.Connection; using Omika.Data.HfSql.Metadata; // --- 1. Charger la configuration Hfsql (avec FilePasswords) --- // Chemin absolu vers config/hfsql-test.local.json à la racine du dépôt. // Le probe est lancé depuis la racine du dépôt (D:\Avalonia\Omika). var configPath = Path.GetFullPath(Path.Combine( Directory.GetCurrentDirectory(), "config", "hfsql-test.local.json")); var config = new ConfigurationBuilder() .AddJsonFile(configPath, optional: false, reloadOnChange: false) .Build(); var hfsqlOptions = new HfsqlOptions(); config.GetSection(HfsqlOptions.SectionName).Bind(hfsqlOptions); bool protectionStdConfigured = !string.IsNullOrWhiteSpace(hfsqlOptions.FilePasswords.ProtectionStd); bool protectionPlusConfigured = !string.IsNullOrWhiteSpace(hfsqlOptions.FilePasswords.ProtectionPlus); Console.WriteLine($"=== Probe FilePassword (base {hfsqlOptions.DatabaseName}) ==="); Console.WriteLine($"ProtectionStd configurée : {(protectionStdConfigured ? "OUI" : "NON")}"); Console.WriteLine($"ProtectionPlus configurée : {(protectionPlusConfigured ? "OUI" : "NON")}"); Console.WriteLine(); // --- 2. Reproduire le mécanisme de l'API : BusinessOleDbConnection --- var factory = new HfSqlOleDbConnectionFactory(); await using var business = new BusinessOleDbConnection(hfsqlOptions, factory); // --- 3. Tables à tester : nom logique, groupe attendu (modèles physiques), colonne PK --- var tables = new[] { new { Logical = "Client", Group = "ProtectionStd", Column = "CL_PKID" }, new { Logical = "Lieu", Group = "ProtectionStd", Column = "LI_PKID" }, new { Logical = "ParametreMetier", Group = "ProtectionStd", Column = "PA_PKID" }, }; // --- 4. Instrumenter la fabrique pour savoir quels fichiers reçoivent le mot de passe --- // La fabrique construit les Extended Properties via BuildExtendedPropertiesFromFilePasswords, // qui dérive désormais la liste des fichiers protégés depuis les modèles physiques // (attributs HfSqlTable avec Groups). On reproduit cette logique pour déterminer si // chaque table est couverte par le mot de passe. var coveredByFactory = GetFactoryCoveredFiles(); Console.WriteLine("--- Couverture des mots de passe par la fabrique (mécanisme API) ---"); foreach (var t in tables) { bool covered = coveredByFactory.Contains(t.Logical, StringComparer.OrdinalIgnoreCase); Console.WriteLine($" {t.Logical,-18} groupe={t.Group,-14} password_applied_par_fabrique={(covered ? "OUI" : "NON")}"); } Console.WriteLine(); // --- 5. Ouvrir la connexion (même mécanisme que l'API) et tester chaque table --- try { await business.OpenAsync(); Console.WriteLine("Connexion OLE DB ouverte (mécanisme API)."); Console.WriteLine(); foreach (var t in tables) { await ProbeTableAsync(business, t.Logical, t.Group, t.Column); } } catch (Exception ex) { Console.WriteLine($"ERREUR ouverture connexion: {ex.Message}"); } Console.WriteLine(); Console.WriteLine("Probe FilePassword terminé (lecture seule)."); // --- Helpers --- static async Task ProbeTableAsync( IHfsqlConnection connection, string logical, string group, string column) { string sql = $"SELECT TOP 1 {column} FROM {logical}"; Console.WriteLine($"--- {logical} (groupe={group}) ---"); Console.WriteLine($" requête: {sql}"); try { using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var rows = await connection.QueryAsync(sql, cancellationToken: cts.Token); Console.WriteLine($" résultat: OK (rows={rows.Count})"); } catch (Exception ex) { Console.WriteLine($" résultat: ERREUR"); Console.WriteLine($" message: {ex.Message}"); } Console.WriteLine(); } /// /// Reproduit la logique de HfSqlOleDbConnectionFactory.BuildExtendedPropertiesFromFilePasswords /// (dérivée des modèles physiques via les attributs HfSqlTable avec Groups) pour déterminer /// quels fichiers logiques reçoivent un mot de passe via le mécanisme API. /// static HashSet GetFactoryCoveredFiles() { var covered = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var type in typeof(HfSqlOleDbConnectionFactory).Assembly.GetTypes()) { var attribute = type.GetCustomAttribute(); if (attribute is null) continue; foreach (var group in attribute.Groups) { if (group.Equals("ProtectionStd", StringComparison.OrdinalIgnoreCase) || group.Equals("ProtectionPlus", StringComparison.OrdinalIgnoreCase)) { covered.Add(attribute.TableName); } } } return covered; }