111 lines
2.4 KiB
Go
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
|
|
}
|