From f15f46945da5094c66dc695f96aebbd34615a157 Mon Sep 17 00:00:00 2001 From: Janusz Szczypka Date: Wed, 26 Aug 2026 01:13:45 +0000 Subject: [PATCH] Read Enova credentials from configuration file --- README.md | 13 ++--- release/SmartB2B.Enova.Contracts.dll | Bin 19456 -> 19456 bytes release/SmartB2B.Enova.Contracts.pdb | Bin 13880 -> 13880 bytes release/SmartB2B.Enova.Service.dll | Bin 57856 -> 57344 bytes release/SmartB2B.Enova.Service.exe | Bin 152064 -> 152064 bytes release/SmartB2B.Enova.Service.pdb | Bin 24528 -> 24504 bytes release/adapters/SmartB2B.Enova.Adapter.dll | Bin 13312 -> 13312 bytes release/config/enova.json.sample | 4 +- .../Configuration/ServiceSettings.cs | 33 ++++++------ .../config/enova.json.sample | 4 +- tests/SmartB2B.Enova.Tests/Program.cs | 50 +++++++++++++++++- 11 files changed, 71 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index aba3bfc..a797352 100644 --- a/README.md +++ b/README.md @@ -12,16 +12,9 @@ Dedykowana usługa Windows zastępująca proces Node na stanowiskach z enova365. ## Konfiguracja -Plik `config/enova.json` zawiera portal WAMP, ścieżkę instalacji, alias bazy, operatora, definicję dokumentu, magazyn domyślny i tryb zapisu. Repozytorium oraz paczka zawierają tylko `config/enova.json.sample`. Skrypt instalacyjny kopiuje wzorzec do `config/enova.json` wyłącznie wtedy, gdy lokalna konfiguracja jeszcze nie istnieje. +Plik `config/enova.json` zawiera portal WAMP, ścieżkę instalacji, alias bazy, operatora wraz z hasłem, connection string SQL, definicję dokumentu, magazyn domyślny i tryb zapisu. Repozytorium oraz paczka zawierają tylko `config/enova.json.sample`. Skrypt instalacyjny kopiuje wzorzec do `config/enova.json` wyłącznie wtedy, gdy lokalna konfiguracja jeszcze nie istnieje. -Sekrety nie są przechowywane w JSON-ie. Konto usługi musi widzieć dwie zmienne środowiskowe maszyny: - -```powershell -[Environment]::SetEnvironmentVariable('SMARTB2B_ENOVA_PASSWORD', '', 'Machine') -[Environment]::SetEnvironmentVariable('SMARTB2B_SQL_CONNECTION_STRING', 'Server=...;Database=...;User ID=...;Password=...;TrustServerCertificate=True', 'Machine') -``` - -Po zmianie zmiennych trzeba zrestartować usługę. Connection string powinien używać konta SQL o możliwie najmniejszych uprawnieniach; `sql_raw` celowo dopuszcza również polecenia modyfikujące dane dla zgodności z obecną usługą. +Uzupełnij pola `enova.password` i `sql.connectionString` bezpośrednio w lokalnym pliku `config/enova.json`. Po zmianie konfiguracji trzeba zrestartować usługę. Connection string powinien używać konta SQL o możliwie najmniejszych uprawnieniach; `sql_raw` celowo dopuszcza również polecenia modyfikujące dane dla zgodności z obecną usługą. ## Budowanie i testy @@ -50,7 +43,7 @@ Kontrola konfiguracji i dynamicznego ładowania, bez zapisu do bazy: Skrypt odtwarza katalog `release` z hostem, adapterem, wzorcem konfiguracji i WinSW. Repozytorium zawiera również gotowy, skompilowany katalog `release`, więc na komputerze produkcyjnym nie trzeba instalować SDK. Przed instalacją: 1. Skopiuj katalog `release` na komputer produkcyjny. Możesz skopiować `release/config/enova.json.sample` do `release/config/enova.json` i uzupełnić go przed instalacją; jeżeli tego nie zrobisz, `install.cmd` utworzy plik automatycznie. -2. Ustaw sekrety maszyny. +2. Uzupełnij w `release/config/enova.json` hasło operatora i connection string SQL. 3. Zatrzymaj starą usługę Node dla tego samego portalu WAMP. 4. Skonfiguruj usługę do pracy pod dedykowanym kontem Windows, które potrafi uruchomić Enovę, widzi jej bazę i licencję. 5. Jako administrator uruchom `release/daemon/install.cmd`. diff --git a/release/SmartB2B.Enova.Contracts.dll b/release/SmartB2B.Enova.Contracts.dll index c680eb48fa51ff076dbbdb15caa76138f7e2b633..47b969b368fe685b51677bd988f89eedbb66583f 100644 GIT binary patch delta 237 zcmZpe!Pqc^aY6@6=IZc28+%l21fuKmW`4+w^jWaX>D_6j*E*XI*lc0eFi1^FO|djc zHA^xww=_#OO*Jt~O-i#&F-%S|OfoSyHL^%CO|>*loIJJ0YfT73K&~5 zfY@dXNeo5|<_wlVRx*PrP{ahtN(G9h0mV`n41uB`G6^Vd4wN@yumJKw>MVg|;^y=2 GhAaST=1SoJ delta 237 zcmZpe!Pqc^aY6@6>^g<+jXf$h0t$_%5`$JJy6>Gmjmf3LL16O%n=Q;5W(KCoW=ZBL zMu}!gmIjGw#^y#QNk*wgDXEr;mX^sWNlBI|Nv39&ljk^?u$->gF=_G@hX4Ts0ewD( z%G(b6wCCvFoN>f{vWeqF1*o7x9aIpcTC9dYw|HXAQx?S=8k?Uw&Sv#DV=!PaWk_Z) zV@P5!XGmc%Vn_tDErH^R3~3C;Kv5$G6QHaSLn;ub07*-rj3p2z19?e6XbGlGf%+^r JpLaK80RU8oMvedg diff --git a/release/SmartB2B.Enova.Contracts.pdb b/release/SmartB2B.Enova.Contracts.pdb index 4fbbca9fbe37632ede644f3d9571b5c66650db28..1a3ce34bf51151d24f983547d0020e780830adac 100644 GIT binary patch delta 429 zcmV;e0aE_BY`AQYd=#o?I1nHqO+~NV$W7=kHsMdD+On~bjthTh-~rYk5+O#xn(8AT zbgJevr(}A4XiMH_^*G`SaJ$WcV;BSg0IicvYXUJ4hVO#^Ver&a+*R?Two*{3rH4XM zX%D4`*<^MNWRsH2D*Nx7wPjKIfd?n2%uJqlGReeo`>fV%#4${;VB5~fkV7VUw|7>y z-Y5^kN`f7Fs1tu6DFK14)lrpNr_VQNGV&n;T%AmnCdjb_frTefMp)-aFeJ3Wt+Ec# zNZ2W@g9o(r3@WW@yrD1cKyp-z?$2^+Ux_n;^>OXi_9g-x+9U3OR(Re5Z)E`ok zj%8QKZqgqOde?G5;{l#7`|PYN1fR9FYsH$*O8mdS`>*|QIA+xlJgsJh(h^>sVw#7E XSUAjbG7Jbp2hA`L&BiCQqYafPR-?`8 delta 429 zcmV;e0aE_BY`AQYd=xMcFAe~C+d#f6oGsay#6Qb;xRSAujthVMPW3EjUd{E3auBI~ z6~W7UuR(vbLS5B1!kmyO4|08hV;BSg0IicvO9L?whVO;`hryE~?$*_|tcqY4D;@-C ziyp+oB$?d}WD`kdmHqc-s}#i#dg$bonaT4`CYdxn+Nli(X$lwEvOB8Cl1C23>AwT+@ekBzfA1uO;Ck{iWtzw`MqKgSHhcyTH_(f8QnxDownMb~Z+a zgC`7u8ezJ#p9#s;XRL6|3)=3A*=x}{WsnFaYQ}*W4&DK?qYafPE1l5Z diff --git a/release/SmartB2B.Enova.Service.dll b/release/SmartB2B.Enova.Service.dll index 2ba3fdfff5c95d6bcc403ba9e7ca24649ab95e15..132d6d344db0e420afbf8d3a14ef85a439e451d5 100644 GIT binary patch delta 16937 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 delta 17317 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 DEU6C) diff --git a/release/SmartB2B.Enova.Service.exe b/release/SmartB2B.Enova.Service.exe index fa0cab780c38205c1ef5cf774503898a3989161d..ceb7c37d942c5faaf6b6404b7e4d7e478ef99a9e 100644 GIT binary patch delta 99 zcmZoz!r1^sEsR^3ruh0BFr+f1fUzY5h;7D@#9+i=&R_{-B{P@;MNELKRG?@YP%MSP f5GV>FlYrvpKzSnu3m_k)&Jsu_Zh!2{B+CK-5rPuq delta 99 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 delta 4789 zcmZvf30PIt7RT4V_uL7P!OJM4;eZH*&j1B33JHP(JV6l*D})rep%7@y(}%?f1Pu$p8UAq_uqT})>?a=z4zH?pK}|U z#Hl8+?%q-_J5lr^q8q4#4QLn6o;hjSqq7J<|3D%Mb@Z4*3PyV!w}+0&9fEonI3^dI z`S|oQu(8{GrTXNQVe-7jKZYGW_(RhYakzS2Sin#4wL<<-z0mSKUwve_jU5e8juIfA z98hYJXr{$L-V~JVO;rQDY0UsQ)t^MlKyFC%;y_K?QL|njsC1X2oD%)626&J$g#$fk zVu}Y%h2}t&&>CnXv>Dn7y$S7y-h)m+AE(%;6{<+J(R0u?=qD&F%|_8_CW?hNL0h0# zpf}U_I%aB0Gm|mIVI~jA59;U89I0rhI@HmbDN{9CXoSN;(;Ze?tg?~XU3Emdk$OUL zP=6=|%7Aj9{B%xeprUjG)j+R8hoNTG?oA)33pxjV0kuI_p`V~@&`rqf93-d<9fw+O+1TzuuV;EtT_(5PKO1>vnaB?H$a33ElmJdv*+l7RXF(%w z`8m!){@E4^&E~e1?n=wHQXeQmHL#I?MtXIqR__^Vqkx5X659dAMVaUEOHo~mQ^PrJ=dOoM2; zE@3zD6So5}Wuh56=J=U9WE{Nv~RG)@IK zdxOvDm}h)W$GoKH@8AnM<`w(w4!%es&RZAQgjvI&GHbFeiau2k&)pGI%$5H~11cqiG-v{Nov1roZ!lDCU;G3;bW* z!EHMJ$VBAkiHHrugqTy1{~Ru{2R7zZ@K@k%%uX26V0aC|k*)v-_&S)M;VTr6^FbTn zAn-Rj4gz1*@lNSB^XPkO`%g zoX23oHyFS}eMmfM7TP{)QeU++sk6c77VMscPf)U}c7N;)zI-D}BW1!X(WfX)v75CnQ_0&)Q;2^+!A*RFSTu?Ul1wL zaFix>u2%KJM)ees)Yq#?U00lvh|x+x7tuCQe>Pz4_9o*J6p4L?RGeta0DOoIs>bdFYgE|)K3&p9nxynd;P~w6?{O~41d<-T-%@|_~u5uCEw~cbJ?T2A2 zmmrgga(#MZsn#f)?BNAfmR2**Aj*%+)?h0=li3<be95iYTSa6a5dbD2dtkzimyY5{tYxEWVJpt+cK3XWK)o=6&AL%Z4ol8n z-uagKJ2!7DtMHqgS~@Mc==>+wX1*8uuRmK}&hEEoaO&c+uDA)imCM85Pw;KNZ22>C zjib-obBmH+^_~!#x6t?D&_ANmOV>{c&9Ud6S^d{|3|)*}bre^I$>_D%Ze=%Ws0&h?sK z8ZLLd-_Iu{dH=KT`E! zdP(%;jTL?tgygdzZua?Ef<|NEsI^?kSpITUk<55*K?WqQUA>JHh|u zk1a7uM_z<-D%?Za8$RB2rOLM|r_LU6!!x*KM%k}?`q)qB25uaC_lTuy6VKn+=a^I1 zJNE7#_6$*D);_#e^_V12cpG+Bt$CaQP(;RI2a-h_7w*+>bez3 zqSJ^&8RF0be2tXC(Se;^oFDomPg55f zFX2J7OI8a-8gOn2Lq&wB@2oSXh3uGF)9CvnI}5SiFLkdH~$?o@8A@S_9+S%rKSEaVl|iU5x!GmXMY6;-H=F6!l3Y{2oA&BepY z@}j7&Q*HPoC0PSWNHh3*uY9(0vZ%YWB9g&W(Ss{#L5xZZ;ypoL6?c1*LF&q9jU>yx zxHidhUyYYUXuKp^<7F;h=HkkJn!hqh^RI}}ctyO%Ppf&HCi&?E&9JJc7O*Ook615R zPV^)%X@)2HNO&=YNWDBslBR31)#^cRlB?4-R$R%Ic>ZvUlB;ugi zjnufdhZhy&bs*RD^CW+10e{I-yqV+|134f}-fZGJPJT(PyUAPBI!xZG)^_=2wf2>_ znbfX%W4vc%cm$i)YcA+;V>k()Lk35MTm=an@USXpEiEK6>!eB{>YcdIonc^uZVND4MDzA e&e^6!JaE+WYBu~6IOeMI?E_=PcS^>CbN&y^Bwlm? diff --git a/release/adapters/SmartB2B.Enova.Adapter.dll b/release/adapters/SmartB2B.Enova.Adapter.dll index 89914256271a643efe0fac77a3f6aa0e526849f6..8eaf0d9cc226187411d86e00d602f9bc5c9403e2 100644 GIT binary patch delta 235 zcmZq3Xvmn*!NR%c3EW~;R7qx+(no0q7^v1k~irlh7=8l;*f z8JSy}C7Y(2n58DAS*92!rx+%gn420|q?o2!nkG)x(otfu`!{FF;IO9l|z zj3J4^h{2q}639wsFa?U309mO((KMh~3WFg~6htNg#m#~8Mhq4}K1iJ E00H$%iU0rr delta 235 zcmZq3Xvmn*!Q!CpzkXv6hq{1<-X+EsUw!8lC+}>E=`xPqyhJ^YMZ?U%G}$c4JjE!{ zEXmR!G0oWA$Rx=q)hH#^GSSj9IVCB{G9}5>%yP1pjuH!JchjQD0XhK!cKte=r%rEh z+|@FF+WHetnv*x^^eR9FAHoDds=;kn1^vyjy8JBuW()=lrVPmpW(-LT z<_sweMhuBywk1$Jks*!27$|DQU;>miVn_wz6d-8{l(7WDWFRjI2ra?1DNvu~=G}&_ FOaN&cN2dS) diff --git a/release/config/enova.json.sample b/release/config/enova.json.sample index c21bbcc..0754aa2 100644 --- a/release/config/enova.json.sample +++ b/release/config/enova.json.sample @@ -8,13 +8,13 @@ "installationPath": "C:\\Program Files (x86)\\Soneta\\enova365 2604.4.4", "database": "Firma demo", "operator": "Administrator", - "passwordEnvironmentVariable": "SMARTB2B_ENOVA_PASSWORD", + "password": "", "documentDefinition": "ZO", "defaultWarehouseCode": null, "saveMode": "Buffer" }, "sql": { - "connectionStringEnvironmentVariable": "SMARTB2B_SQL_CONNECTION_STRING", + "connectionString": "Server=...;Database=...;User ID=...;Password=...;TrustServerCertificate=True", "commandTimeoutSeconds": 30 }, "diagnostics": { diff --git a/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs b/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs index 5b52f24..d0a8b32 100644 --- a/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs +++ b/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs @@ -48,19 +48,8 @@ public sealed class ServiceSettings public RuntimeSettings ResolveRuntimeSettings() { - var enovaPassword = Environment.GetEnvironmentVariable(Enova.PasswordEnvironmentVariable); - if (enovaPassword is null) - { - throw new ConfigurationException( - $"Brak zmiennej środowiskowej {Enova.PasswordEnvironmentVariable} z hasłem operatora Enovy."); - } - - var connectionString = Environment.GetEnvironmentVariable(Sql.ConnectionStringEnvironmentVariable); - if (string.IsNullOrWhiteSpace(connectionString)) - { - throw new ConfigurationException( - $"Brak zmiennej środowiskowej {Sql.ConnectionStringEnvironmentVariable} z connection stringiem SQL."); - } + var enovaPassword = Enova.Password + ?? throw new ConfigurationException("Parametr 'enova.password' jest wymagany."); var installationPath = Path.GetFullPath( Environment.ExpandEnvironmentVariables(Enova.InstallationPath)); @@ -72,7 +61,7 @@ public sealed class ServiceSettings Enova.DocumentDefinition, Enova.DefaultWarehouseCode, Enova.SaveMode), - connectionString, + Sql.ConnectionString, Sql.CommandTimeoutSeconds, ResolvePath(Diagnostics.LogDirectory), Diagnostics.LogPrefix); @@ -90,9 +79,9 @@ public sealed class ServiceSettings Require(Enova.InstallationPath, "enova.installationPath", errors); Require(Enova.Database, "enova.database", errors); Require(Enova.Operator, "enova.operator", errors); - Require(Enova.PasswordEnvironmentVariable, "enova.passwordEnvironmentVariable", errors); + RequirePresent(Enova.Password, "enova.password", errors); Require(Enova.DocumentDefinition, "enova.documentDefinition", errors); - Require(Sql.ConnectionStringEnvironmentVariable, "sql.connectionStringEnvironmentVariable", errors); + Require(Sql.ConnectionString, "sql.connectionString", errors); if (Sql.CommandTimeoutSeconds <= 0) { errors.Add("sql.commandTimeoutSeconds musi być większe od zera."); @@ -112,6 +101,14 @@ public sealed class ServiceSettings } } + private static void RequirePresent(string? value, string name, ICollection errors) + { + if (value is null) + { + errors.Add($"Parametr '{name}' jest wymagany."); + } + } + private static string ResolvePath(string path) => Path.IsPathRooted(path) ? Path.GetFullPath(path) : Path.GetFullPath(path, AppContext.BaseDirectory); } @@ -131,7 +128,7 @@ public sealed class EnovaSettings public string Operator { get; init; } = "Administrator"; - public string PasswordEnvironmentVariable { get; init; } = "SMARTB2B_ENOVA_PASSWORD"; + public string? Password { get; init; } public string DocumentDefinition { get; init; } = "ZO"; @@ -142,7 +139,7 @@ public sealed class EnovaSettings public sealed class SqlSettings { - public string ConnectionStringEnvironmentVariable { get; init; } = "SMARTB2B_SQL_CONNECTION_STRING"; + public string ConnectionString { get; init; } = string.Empty; public int CommandTimeoutSeconds { get; init; } = 30; } diff --git a/src/SmartB2B.Enova.Service/config/enova.json.sample b/src/SmartB2B.Enova.Service/config/enova.json.sample index c21bbcc..0754aa2 100644 --- a/src/SmartB2B.Enova.Service/config/enova.json.sample +++ b/src/SmartB2B.Enova.Service/config/enova.json.sample @@ -8,13 +8,13 @@ "installationPath": "C:\\Program Files (x86)\\Soneta\\enova365 2604.4.4", "database": "Firma demo", "operator": "Administrator", - "passwordEnvironmentVariable": "SMARTB2B_ENOVA_PASSWORD", + "password": "", "documentDefinition": "ZO", "defaultWarehouseCode": null, "saveMode": "Buffer" }, "sql": { - "connectionStringEnvironmentVariable": "SMARTB2B_SQL_CONNECTION_STRING", + "connectionString": "Server=...;Database=...;User ID=...;Password=...;TrustServerCertificate=True", "commandTimeoutSeconds": 30 }, "diagnostics": { diff --git a/tests/SmartB2B.Enova.Tests/Program.cs b/tests/SmartB2B.Enova.Tests/Program.cs index 3c6342b..93b664d 100644 --- a/tests/SmartB2B.Enova.Tests/Program.cs +++ b/tests/SmartB2B.Enova.Tests/Program.cs @@ -1,4 +1,5 @@ using SmartB2B.Enova.Contracts; +using SmartB2B.Enova.Service.Configuration; using SmartB2B.Enova.Service.Orders; using SmartB2B.Enova.Service.Rpc; using SmartB2B.Enova.Service.Runtime; @@ -23,7 +24,8 @@ var tests = new (string Name, Func Run)[] ("Warstwa WAMP wysyła wynik jako kwargs", WampKeywordWireResult), ("Brak waluty zwraca stabilny błąd", MissingCurrency), ("Waluta inna niż PLN jest odrzucana", UnsupportedCurrency), - ("Brak katalogu Enovy jest wykrywany", MissingEnovaDirectory) + ("Brak katalogu Enovy jest wykrywany", MissingEnovaDirectory), + ("Sekrety są odczytywane z pliku konfiguracji", SecretsComeFromConfigurationFile) }; var failures = 0; @@ -179,6 +181,52 @@ static Task MissingEnovaDirectory() } } +static Task SecretsComeFromConfigurationFile() +{ + var path = Path.Combine(Path.GetTempPath(), $"enova-settings-{Guid.NewGuid():N}.json"); + try + { + File.WriteAllText(path, """ + { + "portal": "demo", + "wamp": { + "serverUrl": "ws://localhost:8080/", + "reconnectDelaySeconds": 10 + }, + "enova": { + "installationPath": "C:/Enova", + "database": "Firma demo", + "operator": "Administrator", + "password": "haslo-z-pliku", + "documentDefinition": "ZO", + "saveMode": "Buffer" + }, + "sql": { + "connectionString": "Server=db;Database=enova;User ID=user;Password=sql-z-pliku", + "commandTimeoutSeconds": 30 + }, + "diagnostics": { + "logDirectory": "C:/logs", + "logPrefix": "test" + } + } + """); + + var runtime = ServiceSettings.Load(path).ResolveRuntimeSettings(); + + AssertEqual("haslo-z-pliku", runtime.EnovaConfiguration.Connection.Password, "hasło operatora"); + AssertEqual( + "Server=db;Database=enova;User ID=user;Password=sql-z-pliku", + runtime.SqlConnectionString, + "connection string SQL"); + return Task.CompletedTask; + } + finally + { + File.Delete(path); + } +} + static RpcInvocation CreateInvocation() => new( [], new Dictionary