Files
LambdaMail/services/protocols/internal/domain/entity/tls_rpt_report.go
T
Lucas Rayan 880dced9e4 feat: implement message deletion functionality and improve draft handling
- Added `MoveToTrash` method in `WebmailRepository` to move messages to the Trash folder instead of deleting them permanently.
- Introduced `handleDelete` method in `mailAPI` to handle message deletion requests from the client.
- Updated router to include a new route for message deletion.
- Enhanced the compose page to manage draft integrity, ensuring drafts are correctly associated with sent messages.
- Implemented UI changes to allow users to delete messages from the mail folder view.
- Added tests to verify the correct behavior of message deletion and draft handling.
- Updated database migration scripts to reconcile folder counters and ensure accurate unread counts.
- Added tests for TLS-RPT report parsing and webmail repository functionalities.
2026-08-20 15:32:14 -03:00

96 lines
2.5 KiB
Go

package entity
import (
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io"
"time"
)
type TlsRptPolicy struct {
PolicyType string
SuccessCount int
FailureCount int
}
type TlsRptReport struct {
OrganizationName string
ReportID string
Domain string
DateRangeBegin time.Time
DateRangeEnd time.Time
Policies []TlsRptPolicy
}
type tlsRptJsonReport struct {
OrganizationName string `json:"organization-name"`
ReportID string `json:"report-id"`
DateRange struct {
StartDatetime string `json:"start-datetime"`
EndDatetime string `json:"end-datetime"`
} `json:"date-range"`
Policies []struct {
Policy struct {
PolicyType string `json:"policy-type"`
// RFC 8460 section 4.4 names this "policy-domain". Reading it as
// "domain" parsed every real report to a blank domain, so a stored
// report could not be attributed to the domain it was about.
Domain string `json:"policy-domain"`
} `json:"policy"`
Summary struct {
TotalSuccessfulSessionCount int `json:"total-successful-session-count"`
TotalFailureSessionCount int `json:"total-failure-session-count"`
} `json:"summary"`
} `json:"policies"`
}
// ParseTlsRptReport parses JSON or gzipped JSON TLS-RPT report.
func ParseTlsRptReport(payload []byte) (*TlsRptReport, error) {
data := payload
if isGzip(payload) {
gz, err := gzip.NewReader(bytes.NewReader(payload))
if err != nil {
return nil, fmt.Errorf("gzip reader: %w", err)
}
defer gz.Close()
decompressed, err := io.ReadAll(gz)
if err != nil {
return nil, fmt.Errorf("decompress gzip: %w", err)
}
data = decompressed
}
var parsed tlsRptJsonReport
if err := json.Unmarshal(data, &parsed); err != nil {
return nil, fmt.Errorf("unmarshal tls-rpt json: %w", err)
}
beginTime, _ := time.Parse(time.RFC3339, parsed.DateRange.StartDatetime)
endTime, _ := time.Parse(time.RFC3339, parsed.DateRange.EndDatetime)
domain := ""
if len(parsed.Policies) > 0 {
domain = parsed.Policies[0].Policy.Domain
}
report := &TlsRptReport{
OrganizationName: parsed.OrganizationName,
ReportID: parsed.ReportID,
Domain: domain,
DateRangeBegin: beginTime,
DateRangeEnd: endTime,
}
for _, p := range parsed.Policies {
report.Policies = append(report.Policies, TlsRptPolicy{
PolicyType: p.Policy.PolicyType,
SuccessCount: p.Summary.TotalSuccessfulSessionCount,
FailureCount: p.Summary.TotalFailureSessionCount,
})
}
return report, nil
}