clientGroupsBlock group references not validated
First of all, thanks for the great project!
However, today I noticed I renamed a block group in `denylists`, but forgot to update the reference in `clientGroupsBlock`:
```yaml
blocking:
blockType: zeroIP
denylists:
base:
- https://...
extra:
- https://...
clientGroupsBlock:
default:
- base
- nonexisting
```
Unfortunately, it seems Blocky isn't validating the list references in `clientGroupsBlock` do actually exist as allowlist/denylist
Unless it's by design, can a validation be added? I would be happy raise a PR if you prefer (I have Golang experience, but not with this project).
## Copilot suggestion
In case it would help, Copilot's 2 cents:
To validate the referenced block groups in [clientGroupsBlock](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html), you need to check that all groups referenced in [ClientGroupsBlock](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) actually exist in either [Denylists](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) or [Allowlists](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html). Based on the codebase, here's what needs to be changed:
### Add Validation in the Configuration
The validation should be added in the [NewBlockingResolver](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) function or in the configuration validation. Here's the recommended approach:
```golang
// ...existing code...
func NewBlockingResolver(ctx context.Context,
cfg config.Blocking,
redis *redis.Client,
bootstrap *Bootstrap,
) (r *BlockingResolver, err error) {
blockHandler, err := createBlockHandler(cfg)
if err != nil {
return nil, fmt.Errorf("failed to create block handler: %w", err)
}
// Validate that all groups referenced in ClientGroupsBlock exist
if err := validateClientGroupsBlock(cfg); err != nil {
return nil, err
}
downloader := lists.NewDownloader(cfg.Loading.Downloads, bootstrap.NewHTTPTransport())
// ...existing code...
}
func validateClientGroupsBlock(cfg config.Blocking) error {
// Collect all defined groups
definedGroups := make(map[string]bool)
for group := range cfg.Denylists {
definedGroups[group] = true
}
for group := range cfg.Allowlists {
definedGroups[group] = true
}
// Check all referenced groups
for clientIdentifier, groups := range cfg.ClientGroupsBlock {
for _, group := range groups {
if !definedGroups[group] {
return fmt.Errorf("clientGroupsBlock references unknown group '%s' for client '%s'. Available groups: %v",
group, clientIdentifier, maps.Keys(definedGroups))
}
}
}
return nil
}
// ...existing code...
```
### Alternative: Add to Config Validation
You could also add this validation to the [Blocking](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) configuration struct:
```golang
// ...existing code...
// Validate checks that all referenced groups exist
func (c *Blocking) Validate() error {
definedGroups := make(map[string]bool)
for group := range c.Denylists {
definedGroups[group] = true
}
for group := range c.Allowlists {
definedGroups[group] = true
}
for clientIdentifier, groups := range c.ClientGroupsBlock {
for _, group := range groups {
if !definedGroups[group] {
return fmt.Errorf("clientGroupsBlock references unknown group '%s' for client '%s'",
group, clientIdentifier)
}
}
}
return nil
}
// ...existing code...
```
The validation ensures that every group name listed in [ClientGroupsBlock](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) (like "gr1", "defaultGroup", "ads", etc.) must have a corresponding entry in either the [Denylists](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) or [Allowlists](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) maps. This prevents runtime errors when trying to match domains against non-existent groups.
2 条评论