pcmt/modules/localbreach/breach.go
surtur 7a877b01bb
All checks were successful
continuous-integration/drone/push Build is passing
go: implement import of local breach data
2023-08-20 05:20:33 +02:00

111 lines
2.4 KiB
Go

// Copyright 2023 wanderer <a_mirre at utb dot cz>
// SPDX-License-Identifier: AGPL-3.0-only
package localbreach
import (
"bytes"
"context"
"io"
"os"
"git.dotya.ml/mirre-mt/pcmt/ent"
"git.dotya.ml/mirre-mt/pcmt/ent/schema"
"git.dotya.ml/mirre-mt/pcmt/slogging"
"golang.org/x/exp/slog"
"gopkg.in/yaml.v3"
)
type CtxKey struct{}
// Load loads local breach data and returns a pointer to the slice of the
// structs, of which each holds one YAML document on successful import, error
// otherwise.
func Load(path string) (*[]schema.ImportSchema, error) {
b, err := os.ReadFile(path)
if err != nil {
return nil, err
}
lb, err := loadLocalBreach(b)
if err != nil {
return nil, err
}
return lb, nil
}
func loadLocalBreach(b []byte) (*[]schema.ImportSchema, error) {
r := bytes.NewReader(b)
decoder := yaml.NewDecoder(r)
lb := make([]schema.ImportSchema, 0)
var is schema.ImportSchema
for {
if err := decoder.Decode(&is); err != nil {
if err != io.EOF {
return nil, err
}
break // get out when there are no more documents to read.
}
lb = append(lb, is)
}
return &lb, nil
}
// ImportLocalBreach imports data that from YAML files into the database. The
// data must adhere to the ImportSchema.
func ImportLocalBreach(ctx context.Context, db *ent.Client, b *[]schema.ImportSchema) ([]*ent.LocalBreach, error) {
slogger := ctx.Value(CtxKey{}).(*slogging.Slogger)
log := *slogger
log.Logger = log.With(
slog.Group("pcmt extra", slog.String("module", "modules/localbreach")),
)
var err error
var lbs []*ent.LocalBreach
// go through the documents, abort saving to DB on err of one.
for _, breach := range *b {
lb, err := db.LocalBreach.
Create().
SetName(breach.Name).
SetNillableDescription(&breach.Description).
SetIsVerified(breach.IsVerified).
SetContainsEmails(breach.ContainsEmails).
SetContainsUsernames(breach.ContainsUsernames).
SetContainsPasswords(breach.ContainsPasswords).
SetContainsHashes(breach.ContainsHashes).
SetNillableHashSalted(&breach.HashSalted).
SetNillableHashPeppered(&breach.HashPeppered).
SetNillableHashType(&breach.HashType).
SetNillableDate(&breach.Date).
SetData(&breach.Data).
Save(ctx)
if err != nil {
break
}
lbs = append(lbs, lb)
}
switch {
case lbs == nil && err != nil:
return nil, err
case ent.IsConstraintError(err):
return nil, err
case err == nil && lbs != nil:
return lbs, nil
}
return nil, err
}