@@ -10,8 +10,10 @@ import (
1010 "github.com/sirosfoundation/g119612/pkg/logging"
1111 _ "github.com/sirosfoundation/go-trust/docs/swagger" // Import generated docs
1212 "github.com/sirosfoundation/go-trust/pkg/api"
13+ "github.com/sirosfoundation/go-trust/pkg/config"
1314 "github.com/sirosfoundation/go-trust/pkg/registry"
1415 "github.com/sirosfoundation/go-trust/pkg/registry/etsi"
16+ "github.com/sirosfoundation/go-trust/pkg/registry/static"
1517 swaggerFiles "github.com/swaggo/files"
1618 ginSwagger "github.com/swaggo/gin-swagger"
1719)
@@ -67,13 +69,18 @@ func usage() {
6769 fmt .Fprintln (os .Stderr , "\n ETSI TSL Registry Options:" )
6870 fmt .Fprintln (os .Stderr , " --etsi-cert-bundle Path to PEM file with trusted CA certificates" )
6971 fmt .Fprintln (os .Stderr , " --etsi-tsl-files Comma-separated list of local TSL XML files" )
72+ fmt .Fprintln (os .Stderr , "\n Whitelist Registry Options:" )
73+ fmt .Fprintln (os .Stderr , " --registry Registry type: whitelist, always-trusted, never-trusted" )
74+ fmt .Fprintln (os .Stderr , " --whitelist Path to whitelist YAML/JSON config file" )
75+ fmt .Fprintln (os .Stderr , " --whitelist-watch Watch whitelist file for changes (default: true)" )
7076 fmt .Fprintln (os .Stderr , "\n Logging Options:" )
7177 fmt .Fprintln (os .Stderr , " --log-level Logging level: debug, info, warn, error (default: info)" )
7278 fmt .Fprintln (os .Stderr , " --log-format Logging format: text or json (default: text)" )
7379 fmt .Fprintln (os .Stderr , "\n Notes:" )
7480 fmt .Fprintln (os .Stderr , " - For TSL processing (load, transform, sign, publish), use tsl-tool from g119612" )
7581 fmt .Fprintln (os .Stderr , " - This server consumes pre-processed TSL data (PEM bundles or XML files)" )
7682 fmt .Fprintln (os .Stderr , " - Run tsl-tool via cron to update TSL data periodically" )
83+ fmt .Fprintln (os .Stderr , " - Use --registry=whitelist --whitelist=/path/to/whitelist.yaml for simple deployments" )
7784 fmt .Fprintln (os .Stderr , "" )
7885}
7986
@@ -89,6 +96,11 @@ func main() {
8996 etsiCertBundle := flag .String ("etsi-cert-bundle" , "" , "Path to PEM file with trusted CA certificates" )
9097 etsiTSLFiles := flag .String ("etsi-tsl-files" , "" , "Comma-separated list of local TSL XML files" )
9198
99+ // Whitelist/static registry options
100+ registryType := flag .String ("registry" , "" , "Registry type: whitelist, always-trusted, never-trusted" )
101+ whitelistFile := flag .String ("whitelist" , "" , "Path to whitelist YAML/JSON config file" )
102+ whitelistWatch := flag .Bool ("whitelist-watch" , true , "Watch whitelist file for changes" )
103+
92104 // Logging options
93105 logLevel := flag .String ("log-level" , "info" , "Logging level: debug, info, warn, error" )
94106 logFormat := flag .String ("log-format" , "text" , "Logging format: text or json" )
@@ -133,10 +145,35 @@ func main() {
133145 logging .F ("host" , * host ),
134146 logging .F ("port" , * port ))
135147
136- // TODO: Load configuration file if provided
148+ // Load configuration file if provided
149+ var cfg * config.Config
137150 if * configFile != "" {
138- logger .Warn ("Configuration file support not yet implemented" ,
151+ var err error
152+ cfg , err = config .LoadConfig (* configFile )
153+ if err != nil {
154+ logger .Fatal ("Failed to load configuration file" ,
155+ logging .F ("file" , * configFile ),
156+ logging .F ("error" , err .Error ()))
157+ }
158+ logger .Info ("Loaded configuration from file" ,
139159 logging .F ("file" , * configFile ))
160+
161+ // Use config file values if CLI flags weren't explicitly set
162+ if * host == "127.0.0.1" && cfg .Server .Host != "" {
163+ * host = cfg .Server .Host
164+ }
165+ if * port == "6001" && cfg .Server .Port != "" {
166+ * port = cfg .Server .Port
167+ }
168+ if * externalURL == "" && cfg .Server .ExternalURL != "" {
169+ * externalURL = cfg .Server .ExternalURL
170+ }
171+ if * logLevel == "info" && cfg .Logging .Level != "" {
172+ * logLevel = cfg .Logging .Level
173+ }
174+ if * logFormat == "text" && cfg .Logging .Format != "" {
175+ * logFormat = cfg .Logging .Format
176+ }
140177 }
141178
142179 // Create server context
@@ -145,7 +182,12 @@ func main() {
145182 // Initialize RegistryManager
146183 registryMgr := registry .NewRegistryManager (registry .FirstMatch , 30 * time .Second )
147184
148- // Configure ETSI TSL registry if cert bundle or TSL files provided
185+ // Configure registries from config file
186+ if cfg != nil {
187+ configureRegistriesFromConfig (cfg , registryMgr , logger )
188+ }
189+
190+ // CLI flags override config file - Configure ETSI TSL registry if cert bundle or TSL files provided
149191 if * etsiCertBundle != "" || * etsiTSLFiles != "" {
150192 logger .Info ("Configuring ETSI TSL registry" )
151193
@@ -176,9 +218,40 @@ func main() {
176218
177219 registryMgr .Register (tslRegistry )
178220 logger .Info ("ETSI TSL registry registered" )
179- } else {
180- logger .Warn ("No ETSI TSL configuration provided (use --etsi-cert-bundle or --etsi-tsl-files)" )
181- logger .Warn ("Server will start but ETSI trust evaluation will not be available" )
221+ }
222+
223+ // Configure whitelist/static registry if requested via CLI
224+ switch * registryType {
225+ case "whitelist" :
226+ if * whitelistFile != "" {
227+ logger .Info ("Configuring whitelist registry from file" ,
228+ logging .F ("path" , * whitelistFile ),
229+ logging .F ("watch" , * whitelistWatch ))
230+ whitelistReg , err := static .NewWhitelistRegistryFromFile (* whitelistFile , * whitelistWatch ,
231+ static .WithWhitelistName ("whitelist" ),
232+ static .WithWhitelistDescription ("URL whitelist from " + * whitelistFile ))
233+ if err != nil {
234+ logger .Fatal ("Failed to create whitelist registry" ,
235+ logging .F ("error" , err .Error ()))
236+ }
237+ registryMgr .Register (whitelistReg )
238+ logger .Info ("Whitelist registry registered" )
239+ } else {
240+ logger .Fatal ("--whitelist flag required when using --registry=whitelist" )
241+ }
242+ case "always-trusted" :
243+ logger .Warn ("Using always-trusted registry - ALL trust requests will be approved" )
244+ logger .Warn ("This is only suitable for development/testing!" )
245+ registryMgr .Register (static .NewAlwaysTrustedRegistry ("always-trusted" ))
246+ case "never-trusted" :
247+ logger .Info ("Using never-trusted registry - ALL trust requests will be denied" )
248+ registryMgr .Register (static .NewNeverTrustedRegistry ("never-trusted" ))
249+ case "" :
250+ // No static registry configured
251+ default :
252+ logger .Fatal ("Unknown registry type" ,
253+ logging .F ("type" , * registryType ),
254+ logging .F ("valid" , "whitelist, always-trusted, never-trusted" ))
182255 }
183256
184257 // TODO: Add other registries (OpenID Federation, DID Web) based on config
@@ -219,6 +292,108 @@ func main() {
219292 }
220293}
221294
295+ // configureRegistriesFromConfig configures registries from the loaded config file.
296+ func configureRegistriesFromConfig (cfg * config.Config , registryMgr * registry.RegistryManager , logger logging.Logger ) {
297+ // Configure ETSI TSL registry from config
298+ if cfg .Registries .ETSI != nil && cfg .Registries .ETSI .Enabled {
299+ logger .Info ("Configuring ETSI TSL registry from config file" )
300+ etsiCfg := cfg .Registries .ETSI
301+
302+ tslConfig := etsi.TSLConfig {
303+ Name : etsiCfg .Name ,
304+ Description : etsiCfg .Description ,
305+ CertBundle : etsiCfg .CertBundle ,
306+ TSLFiles : etsiCfg .TSLFiles ,
307+ }
308+
309+ if tslConfig .Name == "" {
310+ tslConfig .Name = "ETSI-TSL"
311+ }
312+ if tslConfig .Description == "" {
313+ tslConfig .Description = "ETSI TS 119612 Trust Status List Registry"
314+ }
315+
316+ tslRegistry , err := etsi .NewTSLRegistry (tslConfig )
317+ if err != nil {
318+ logger .Fatal ("Failed to create ETSI TSL registry from config" ,
319+ logging .F ("error" , err .Error ()))
320+ }
321+
322+ registryMgr .Register (tslRegistry )
323+ logger .Info ("ETSI TSL registry registered from config" )
324+ }
325+
326+ // Configure whitelist registry from config
327+ if cfg .Registries .Whitelist != nil && cfg .Registries .Whitelist .Enabled {
328+ logger .Info ("Configuring whitelist registry from config file" )
329+ wlCfg := cfg .Registries .Whitelist
330+
331+ name := wlCfg .Name
332+ if name == "" {
333+ name = "whitelist"
334+ }
335+ desc := wlCfg .Description
336+ if desc == "" {
337+ desc = "Static URL Whitelist"
338+ }
339+
340+ var whitelistReg * static.WhitelistRegistry
341+ var err error
342+
343+ if wlCfg .ConfigFile != "" {
344+ // Load from external config file
345+ whitelistReg , err = static .NewWhitelistRegistryFromFile (
346+ wlCfg .ConfigFile ,
347+ wlCfg .WatchFile ,
348+ static .WithWhitelistName (name ),
349+ static .WithWhitelistDescription (desc ),
350+ )
351+ if err != nil {
352+ logger .Fatal ("Failed to create whitelist registry from config file" ,
353+ logging .F ("config_file" , wlCfg .ConfigFile ),
354+ logging .F ("error" , err .Error ()))
355+ }
356+ } else {
357+ // Use inline configuration
358+ whitelistReg = static .NewWhitelistRegistry (
359+ static .WithWhitelistName (name ),
360+ static .WithWhitelistDescription (desc ),
361+ static .WithWhitelistConfig (static.WhitelistConfig {
362+ Issuers : wlCfg .Issuers ,
363+ Verifiers : wlCfg .Verifiers ,
364+ TrustedSubjects : wlCfg .TrustedSubjects ,
365+ }),
366+ )
367+ }
368+
369+ registryMgr .Register (whitelistReg )
370+ logger .Info ("Whitelist registry registered from config" ,
371+ logging .F ("issuers" , len (wlCfg .Issuers )),
372+ logging .F ("verifiers" , len (wlCfg .Verifiers )))
373+ }
374+
375+ // Configure always-trusted registry from config
376+ if cfg .Registries .AlwaysTrusted != nil && cfg .Registries .AlwaysTrusted .Enabled {
377+ logger .Warn ("Configuring always-trusted registry from config" )
378+ logger .Warn ("ALL trust requests will be approved - only suitable for development/testing!" )
379+ name := cfg .Registries .AlwaysTrusted .Name
380+ if name == "" {
381+ name = "always-trusted"
382+ }
383+ registryMgr .Register (static .NewAlwaysTrustedRegistry (name ))
384+ }
385+
386+ // Configure never-trusted registry from config
387+ if cfg .Registries .NeverTrusted != nil && cfg .Registries .NeverTrusted .Enabled {
388+ logger .Info ("Configuring never-trusted registry from config" )
389+ name := cfg .Registries .NeverTrusted .Name
390+ if name == "" {
391+ name = "never-trusted"
392+ }
393+ registryMgr .Register (static .NewNeverTrustedRegistry (name ))
394+ }
395+ }
396+
222397// splitCSV splits a comma-separated string and trims whitespace
223398func splitCSV (s string ) []string {
224399 if s == "" {
0 commit comments