Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a merge_key configuration option #57

Merged
merged 1 commit into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ Copy config/config.dist.yaml to config.yaml and change parameters:

* **merge_reports** (bool): merge multiple similar reports to one?

* **merge_key** (string): Go template string used to generate a key to merge
reports. Only used when `merge_reports` is enabled.
Default is `{{ .ReportMetadata.OrgName }}!{{ .ReportMetadata.Email }}!{{ .PolicyPublished.Domain }}`.

* **log_debug** (bool): print debug log messages?

* **log_datetime** (bool): add datetime to log messages?
Expand Down
8 changes: 8 additions & 0 deletions cmd/dmarc-report-converter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type config struct {
Output Output `yaml:"output"`
LookupAddr bool `yaml:"lookup_addr"`
MergeReports bool `yaml:"merge_reports"`
MergeKey string `yaml:"merge_key"`
LogDebug bool `yaml:"log_debug"`
LogDatetime bool `yaml:"log_datetime"`
}
Expand Down Expand Up @@ -50,6 +51,7 @@ type Output struct {
template *template.Template
AssetsPath string `yaml:"assets_path"`
ExternalTemplate string `yaml:"external_template"`
mergeKeyTemplate *template.Template
}

func (o *Output) isStdout() bool {
Expand Down Expand Up @@ -85,6 +87,10 @@ func loadConfig(path string) (*config, error) {
return nil, fmt.Errorf("'input.imap.security' must be one of: tls, starttls, plaintext")
}

if c.MergeKey == "" {
c.MergeKey = `{{ .ReportMetadata.OrgName }}!{{ .ReportMetadata.Email }}!{{ .PolicyPublished.Domain }}`
}

// Determine which template is used based upon Output.Format.
t := txtTmpl
switch c.Output.Format {
Expand Down Expand Up @@ -120,5 +126,7 @@ func loadConfig(path string) (*config, error) {
c.Output.fileTemplate = ft
}

c.Output.mergeKeyTemplate = template.Must(template.New("merge_key").Funcs(tmplFuncs).Parse(c.MergeKey))

return &c, nil
}
2 changes: 1 addition & 1 deletion cmd/dmarc-report-converter/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (c *filesConverter) convert() {
}

func (c *filesConverter) merge() error {
reports, err := groupMergeReports(c.reports)
reports, err := groupMergeReports(c.reports, c.cfg.Output.mergeKeyTemplate)
if err != nil {
return err
}
Expand Down
21 changes: 17 additions & 4 deletions cmd/dmarc-report-converter/merge.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"bytes"
"fmt"
"html/template"
"log"

"github.com/tierpod/dmarc-report-converter/pkg/dmarc"
Expand All @@ -19,11 +21,18 @@ func mergeReports(reports []dmarc.Report) dmarc.Report {
return first
}

func groupReportsKey(r dmarc.Report) string {
return fmt.Sprintf("%v!%v!%v", r.ReportMetadata.OrgName, r.ReportMetadata.Email, r.PolicyPublished.Domain)
func groupReportsKey(r dmarc.Report, t *template.Template) (string, error) {
var buf bytes.Buffer

err := t.Execute(&buf, r)
if err != nil {
return "", err
}

return buf.String(), nil
}

func groupMergeReports(reports []dmarc.Report) ([]dmarc.Report, error) {
func groupMergeReports(reports []dmarc.Report, t *template.Template) ([]dmarc.Report, error) {
if len(reports) == 0 {
return nil, fmt.Errorf("reports list is empty")
}
Expand All @@ -36,7 +45,11 @@ func groupMergeReports(reports []dmarc.Report) ([]dmarc.Report, error) {

// group reports by key
for _, r := range reports {
key := groupReportsKey(r)
key, err := groupReportsKey(r, t)
if err != nil {
return reports, fmt.Errorf("error generating merge key: %s", err)
}

//lint:ignore S1036 we dont want to add nil value
if _, found := grouped[key]; found {
grouped[key] = append(grouped[key], r)
Expand Down
3 changes: 3 additions & 0 deletions config/config.dist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@ lookup_addr: no
# merge multiple similar reports to one?
merge_reports: yes

# Go template string used to generate a key to merge reports.
#merge_reports: "{{ .ReportMetadata.OrgName }}!{{ .ReportMetadata.Email }}!{{ .PolicyPublished.Domain }}"

log_debug: no
log_datetime: no
Loading