From 7a877b01bb8e013177fdec755b3215dfc6fd376c Mon Sep 17 00:00:00 2001 From: surtur Date: Sun, 20 Aug 2023 05:20:33 +0200 Subject: [PATCH] go: implement import of local breach data --- ent/localbreach.go | 50 +++++++++----- ent/localbreach/localbreach.go | 25 ++++--- ent/localbreach/where.go | 103 +++++++--------------------- ent/localbreach_create.go | 44 ++++++------ ent/localbreach_update.go | 67 ++++++++++--------- ent/migrate/schema.go | 5 +- ent/mutation.go | 119 ++++++++++++++++++++++++--------- ent/runtime.go | 2 +- ent/schema/localbreach.go | 38 +++++++++-- modules/localbreach/breach.go | 88 ++++++++++++++++++------ run.go | 10 ++- 11 files changed, 331 insertions(+), 220 deletions(-) diff --git a/ent/localbreach.go b/ent/localbreach.go index 3f5ca05..5189eb9 100644 --- a/ent/localbreach.go +++ b/ent/localbreach.go @@ -3,6 +3,7 @@ package ent import ( + "encoding/json" "fmt" "strings" "time" @@ -10,6 +11,7 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "git.dotya.ml/mirre-mt/pcmt/ent/localbreach" + "git.dotya.ml/mirre-mt/pcmt/ent/schema" "github.com/google/uuid" ) @@ -26,12 +28,14 @@ type LocalBreach struct { Description *string `json:"description,omitempty"` // IsVerified holds the value of the "is_verified" field. IsVerified bool `json:"is_verified,omitempty"` - // ContainsPasswds holds the value of the "contains_passwds" field. - ContainsPasswds bool `json:"contains_passwds,omitempty"` + // ContainsPasswords holds the value of the "contains_passwords" field. + ContainsPasswords bool `json:"contains_passwords,omitempty"` // ContainsHashes holds the value of the "contains_hashes" field. ContainsHashes bool `json:"contains_hashes,omitempty"` // ContainsEmails holds the value of the "contains_emails" field. ContainsEmails bool `json:"contains_emails,omitempty"` + // ContainsUsernames holds the value of the "contains_usernames" field. + ContainsUsernames bool `json:"contains_usernames,omitempty"` // MD5, SHA1, Argon2id... HashType *string `json:"hash_type,omitempty"` // HashSalted holds the value of the "hash_salted" field. @@ -39,7 +43,7 @@ type LocalBreach struct { // HashPeppered holds the value of the "hash_peppered" field. HashPeppered *bool `json:"hash_peppered,omitempty"` // Data holds the value of the "data" field. - Data *string `json:"data,omitempty"` + Data *schema.Data `json:"data,omitempty"` // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at,omitempty"` // Edges holds the relations/edges for other nodes in the graph. @@ -71,9 +75,11 @@ func (*LocalBreach) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case localbreach.FieldIsVerified, localbreach.FieldContainsPasswds, localbreach.FieldContainsHashes, localbreach.FieldContainsEmails, localbreach.FieldHashSalted, localbreach.FieldHashPeppered: + case localbreach.FieldData: + values[i] = new([]byte) + case localbreach.FieldIsVerified, localbreach.FieldContainsPasswords, localbreach.FieldContainsHashes, localbreach.FieldContainsEmails, localbreach.FieldContainsUsernames, localbreach.FieldHashSalted, localbreach.FieldHashPeppered: values[i] = new(sql.NullBool) - case localbreach.FieldName, localbreach.FieldDescription, localbreach.FieldHashType, localbreach.FieldData: + case localbreach.FieldName, localbreach.FieldDescription, localbreach.FieldHashType: values[i] = new(sql.NullString) case localbreach.FieldDate, localbreach.FieldCreatedAt: values[i] = new(sql.NullTime) @@ -125,11 +131,11 @@ func (lb *LocalBreach) assignValues(columns []string, values []any) error { } else if value.Valid { lb.IsVerified = value.Bool } - case localbreach.FieldContainsPasswds: + case localbreach.FieldContainsPasswords: if value, ok := values[i].(*sql.NullBool); !ok { - return fmt.Errorf("unexpected type %T for field contains_passwds", values[i]) + return fmt.Errorf("unexpected type %T for field contains_passwords", values[i]) } else if value.Valid { - lb.ContainsPasswds = value.Bool + lb.ContainsPasswords = value.Bool } case localbreach.FieldContainsHashes: if value, ok := values[i].(*sql.NullBool); !ok { @@ -143,6 +149,12 @@ func (lb *LocalBreach) assignValues(columns []string, values []any) error { } else if value.Valid { lb.ContainsEmails = value.Bool } + case localbreach.FieldContainsUsernames: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field contains_usernames", values[i]) + } else if value.Valid { + lb.ContainsUsernames = value.Bool + } case localbreach.FieldHashType: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field hash_type", values[i]) @@ -165,11 +177,12 @@ func (lb *LocalBreach) assignValues(columns []string, values []any) error { *lb.HashPeppered = value.Bool } case localbreach.FieldData: - if value, ok := values[i].(*sql.NullString); !ok { + if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field data", values[i]) - } else if value.Valid { - lb.Data = new(string) - *lb.Data = value.String + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &lb.Data); err != nil { + return fmt.Errorf("unmarshal field data: %w", err) + } } case localbreach.FieldCreatedAt: if value, ok := values[i].(*sql.NullTime); !ok { @@ -232,8 +245,8 @@ func (lb *LocalBreach) String() string { builder.WriteString("is_verified=") builder.WriteString(fmt.Sprintf("%v", lb.IsVerified)) builder.WriteString(", ") - builder.WriteString("contains_passwds=") - builder.WriteString(fmt.Sprintf("%v", lb.ContainsPasswds)) + builder.WriteString("contains_passwords=") + builder.WriteString(fmt.Sprintf("%v", lb.ContainsPasswords)) builder.WriteString(", ") builder.WriteString("contains_hashes=") builder.WriteString(fmt.Sprintf("%v", lb.ContainsHashes)) @@ -241,6 +254,9 @@ func (lb *LocalBreach) String() string { builder.WriteString("contains_emails=") builder.WriteString(fmt.Sprintf("%v", lb.ContainsEmails)) builder.WriteString(", ") + builder.WriteString("contains_usernames=") + builder.WriteString(fmt.Sprintf("%v", lb.ContainsUsernames)) + builder.WriteString(", ") if v := lb.HashType; v != nil { builder.WriteString("hash_type=") builder.WriteString(*v) @@ -256,10 +272,8 @@ func (lb *LocalBreach) String() string { builder.WriteString(fmt.Sprintf("%v", *v)) } builder.WriteString(", ") - if v := lb.Data; v != nil { - builder.WriteString("data=") - builder.WriteString(*v) - } + builder.WriteString("data=") + builder.WriteString(fmt.Sprintf("%v", lb.Data)) builder.WriteString(", ") builder.WriteString("created_at=") builder.WriteString(lb.CreatedAt.Format(time.ANSIC)) diff --git a/ent/localbreach/localbreach.go b/ent/localbreach/localbreach.go index 447ef22..38e2a62 100644 --- a/ent/localbreach/localbreach.go +++ b/ent/localbreach/localbreach.go @@ -23,12 +23,14 @@ const ( FieldDescription = "description" // FieldIsVerified holds the string denoting the is_verified field in the database. FieldIsVerified = "is_verified" - // FieldContainsPasswds holds the string denoting the contains_passwds field in the database. - FieldContainsPasswds = "contains_passwds" + // FieldContainsPasswords holds the string denoting the contains_passwords field in the database. + FieldContainsPasswords = "contains_passwords" // FieldContainsHashes holds the string denoting the contains_hashes field in the database. FieldContainsHashes = "contains_hashes" // FieldContainsEmails holds the string denoting the contains_emails field in the database. FieldContainsEmails = "contains_emails" + // FieldContainsUsernames holds the string denoting the contains_usernames field in the database. + FieldContainsUsernames = "contains_usernames" // FieldHashType holds the string denoting the hash_type field in the database. FieldHashType = "hash_type" // FieldHashSalted holds the string denoting the hash_salted field in the database. @@ -57,9 +59,10 @@ var Columns = []string{ FieldDate, FieldDescription, FieldIsVerified, - FieldContainsPasswds, + FieldContainsPasswords, FieldContainsHashes, FieldContainsEmails, + FieldContainsUsernames, FieldHashType, FieldHashSalted, FieldHashPeppered, @@ -122,9 +125,9 @@ func ByIsVerified(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldIsVerified, opts...).ToFunc() } -// ByContainsPasswds orders the results by the contains_passwds field. -func ByContainsPasswds(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldContainsPasswds, opts...).ToFunc() +// ByContainsPasswords orders the results by the contains_passwords field. +func ByContainsPasswords(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldContainsPasswords, opts...).ToFunc() } // ByContainsHashes orders the results by the contains_hashes field. @@ -137,6 +140,11 @@ func ByContainsEmails(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldContainsEmails, opts...).ToFunc() } +// ByContainsUsernames orders the results by the contains_usernames field. +func ByContainsUsernames(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldContainsUsernames, opts...).ToFunc() +} + // ByHashType orders the results by the hash_type field. func ByHashType(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldHashType, opts...).ToFunc() @@ -152,11 +160,6 @@ func ByHashPeppered(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldHashPeppered, opts...).ToFunc() } -// ByData orders the results by the data field. -func ByData(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldData, opts...).ToFunc() -} - // ByCreatedAt orders the results by the created_at field. func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() diff --git a/ent/localbreach/where.go b/ent/localbreach/where.go index 3a1be70..7f21ee2 100644 --- a/ent/localbreach/where.go +++ b/ent/localbreach/where.go @@ -76,9 +76,9 @@ func IsVerified(v bool) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldEQ(FieldIsVerified, v)) } -// ContainsPasswds applies equality check predicate on the "contains_passwds" field. It's identical to ContainsPasswdsEQ. -func ContainsPasswds(v bool) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldEQ(FieldContainsPasswds, v)) +// ContainsPasswords applies equality check predicate on the "contains_passwords" field. It's identical to ContainsPasswordsEQ. +func ContainsPasswords(v bool) predicate.LocalBreach { + return predicate.LocalBreach(sql.FieldEQ(FieldContainsPasswords, v)) } // ContainsHashes applies equality check predicate on the "contains_hashes" field. It's identical to ContainsHashesEQ. @@ -91,6 +91,11 @@ func ContainsEmails(v bool) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldEQ(FieldContainsEmails, v)) } +// ContainsUsernames applies equality check predicate on the "contains_usernames" field. It's identical to ContainsUsernamesEQ. +func ContainsUsernames(v bool) predicate.LocalBreach { + return predicate.LocalBreach(sql.FieldEQ(FieldContainsUsernames, v)) +} + // HashType applies equality check predicate on the "hash_type" field. It's identical to HashTypeEQ. func HashType(v string) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldEQ(FieldHashType, v)) @@ -106,11 +111,6 @@ func HashPeppered(v bool) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldEQ(FieldHashPeppered, v)) } -// Data applies equality check predicate on the "data" field. It's identical to DataEQ. -func Data(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldEQ(FieldData, v)) -} - // CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. func CreatedAt(v time.Time) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldEQ(FieldCreatedAt, v)) @@ -306,14 +306,14 @@ func IsVerifiedNEQ(v bool) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldNEQ(FieldIsVerified, v)) } -// ContainsPasswdsEQ applies the EQ predicate on the "contains_passwds" field. -func ContainsPasswdsEQ(v bool) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldEQ(FieldContainsPasswds, v)) +// ContainsPasswordsEQ applies the EQ predicate on the "contains_passwords" field. +func ContainsPasswordsEQ(v bool) predicate.LocalBreach { + return predicate.LocalBreach(sql.FieldEQ(FieldContainsPasswords, v)) } -// ContainsPasswdsNEQ applies the NEQ predicate on the "contains_passwds" field. -func ContainsPasswdsNEQ(v bool) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldNEQ(FieldContainsPasswds, v)) +// ContainsPasswordsNEQ applies the NEQ predicate on the "contains_passwords" field. +func ContainsPasswordsNEQ(v bool) predicate.LocalBreach { + return predicate.LocalBreach(sql.FieldNEQ(FieldContainsPasswords, v)) } // ContainsHashesEQ applies the EQ predicate on the "contains_hashes" field. @@ -336,6 +336,16 @@ func ContainsEmailsNEQ(v bool) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldNEQ(FieldContainsEmails, v)) } +// ContainsUsernamesEQ applies the EQ predicate on the "contains_usernames" field. +func ContainsUsernamesEQ(v bool) predicate.LocalBreach { + return predicate.LocalBreach(sql.FieldEQ(FieldContainsUsernames, v)) +} + +// ContainsUsernamesNEQ applies the NEQ predicate on the "contains_usernames" field. +func ContainsUsernamesNEQ(v bool) predicate.LocalBreach { + return predicate.LocalBreach(sql.FieldNEQ(FieldContainsUsernames, v)) +} + // HashTypeEQ applies the EQ predicate on the "hash_type" field. func HashTypeEQ(v string) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldEQ(FieldHashType, v)) @@ -451,61 +461,6 @@ func HashPepperedNotNil() predicate.LocalBreach { return predicate.LocalBreach(sql.FieldNotNull(FieldHashPeppered)) } -// DataEQ applies the EQ predicate on the "data" field. -func DataEQ(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldEQ(FieldData, v)) -} - -// DataNEQ applies the NEQ predicate on the "data" field. -func DataNEQ(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldNEQ(FieldData, v)) -} - -// DataIn applies the In predicate on the "data" field. -func DataIn(vs ...string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldIn(FieldData, vs...)) -} - -// DataNotIn applies the NotIn predicate on the "data" field. -func DataNotIn(vs ...string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldNotIn(FieldData, vs...)) -} - -// DataGT applies the GT predicate on the "data" field. -func DataGT(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldGT(FieldData, v)) -} - -// DataGTE applies the GTE predicate on the "data" field. -func DataGTE(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldGTE(FieldData, v)) -} - -// DataLT applies the LT predicate on the "data" field. -func DataLT(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldLT(FieldData, v)) -} - -// DataLTE applies the LTE predicate on the "data" field. -func DataLTE(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldLTE(FieldData, v)) -} - -// DataContains applies the Contains predicate on the "data" field. -func DataContains(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldContains(FieldData, v)) -} - -// DataHasPrefix applies the HasPrefix predicate on the "data" field. -func DataHasPrefix(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldHasPrefix(FieldData, v)) -} - -// DataHasSuffix applies the HasSuffix predicate on the "data" field. -func DataHasSuffix(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldHasSuffix(FieldData, v)) -} - // DataIsNil applies the IsNil predicate on the "data" field. func DataIsNil() predicate.LocalBreach { return predicate.LocalBreach(sql.FieldIsNull(FieldData)) @@ -516,16 +471,6 @@ func DataNotNil() predicate.LocalBreach { return predicate.LocalBreach(sql.FieldNotNull(FieldData)) } -// DataEqualFold applies the EqualFold predicate on the "data" field. -func DataEqualFold(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldEqualFold(FieldData, v)) -} - -// DataContainsFold applies the ContainsFold predicate on the "data" field. -func DataContainsFold(v string) predicate.LocalBreach { - return predicate.LocalBreach(sql.FieldContainsFold(FieldData, v)) -} - // CreatedAtEQ applies the EQ predicate on the "created_at" field. func CreatedAtEQ(v time.Time) predicate.LocalBreach { return predicate.LocalBreach(sql.FieldEQ(FieldCreatedAt, v)) diff --git a/ent/localbreach_create.go b/ent/localbreach_create.go index 5d2c252..71922bb 100644 --- a/ent/localbreach_create.go +++ b/ent/localbreach_create.go @@ -11,6 +11,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "git.dotya.ml/mirre-mt/pcmt/ent/localbreach" + "git.dotya.ml/mirre-mt/pcmt/ent/schema" "git.dotya.ml/mirre-mt/pcmt/ent/trackedbreaches" "github.com/google/uuid" ) @@ -62,9 +63,9 @@ func (lbc *LocalBreachCreate) SetIsVerified(b bool) *LocalBreachCreate { return lbc } -// SetContainsPasswds sets the "contains_passwds" field. -func (lbc *LocalBreachCreate) SetContainsPasswds(b bool) *LocalBreachCreate { - lbc.mutation.SetContainsPasswds(b) +// SetContainsPasswords sets the "contains_passwords" field. +func (lbc *LocalBreachCreate) SetContainsPasswords(b bool) *LocalBreachCreate { + lbc.mutation.SetContainsPasswords(b) return lbc } @@ -80,6 +81,12 @@ func (lbc *LocalBreachCreate) SetContainsEmails(b bool) *LocalBreachCreate { return lbc } +// SetContainsUsernames sets the "contains_usernames" field. +func (lbc *LocalBreachCreate) SetContainsUsernames(b bool) *LocalBreachCreate { + lbc.mutation.SetContainsUsernames(b) + return lbc +} + // SetHashType sets the "hash_type" field. func (lbc *LocalBreachCreate) SetHashType(s string) *LocalBreachCreate { lbc.mutation.SetHashType(s) @@ -123,19 +130,11 @@ func (lbc *LocalBreachCreate) SetNillableHashPeppered(b *bool) *LocalBreachCreat } // SetData sets the "data" field. -func (lbc *LocalBreachCreate) SetData(s string) *LocalBreachCreate { +func (lbc *LocalBreachCreate) SetData(s *schema.Data) *LocalBreachCreate { lbc.mutation.SetData(s) return lbc } -// SetNillableData sets the "data" field if the given value is not nil. -func (lbc *LocalBreachCreate) SetNillableData(s *string) *LocalBreachCreate { - if s != nil { - lbc.SetData(*s) - } - return lbc -} - // SetCreatedAt sets the "created_at" field. func (lbc *LocalBreachCreate) SetCreatedAt(t time.Time) *LocalBreachCreate { lbc.mutation.SetCreatedAt(t) @@ -244,8 +243,8 @@ func (lbc *LocalBreachCreate) check() error { if _, ok := lbc.mutation.IsVerified(); !ok { return &ValidationError{Name: "is_verified", err: errors.New(`ent: missing required field "LocalBreach.is_verified"`)} } - if _, ok := lbc.mutation.ContainsPasswds(); !ok { - return &ValidationError{Name: "contains_passwds", err: errors.New(`ent: missing required field "LocalBreach.contains_passwds"`)} + if _, ok := lbc.mutation.ContainsPasswords(); !ok { + return &ValidationError{Name: "contains_passwords", err: errors.New(`ent: missing required field "LocalBreach.contains_passwords"`)} } if _, ok := lbc.mutation.ContainsHashes(); !ok { return &ValidationError{Name: "contains_hashes", err: errors.New(`ent: missing required field "LocalBreach.contains_hashes"`)} @@ -253,6 +252,9 @@ func (lbc *LocalBreachCreate) check() error { if _, ok := lbc.mutation.ContainsEmails(); !ok { return &ValidationError{Name: "contains_emails", err: errors.New(`ent: missing required field "LocalBreach.contains_emails"`)} } + if _, ok := lbc.mutation.ContainsUsernames(); !ok { + return &ValidationError{Name: "contains_usernames", err: errors.New(`ent: missing required field "LocalBreach.contains_usernames"`)} + } if _, ok := lbc.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "LocalBreach.created_at"`)} } @@ -307,9 +309,9 @@ func (lbc *LocalBreachCreate) createSpec() (*LocalBreach, *sqlgraph.CreateSpec) _spec.SetField(localbreach.FieldIsVerified, field.TypeBool, value) _node.IsVerified = value } - if value, ok := lbc.mutation.ContainsPasswds(); ok { - _spec.SetField(localbreach.FieldContainsPasswds, field.TypeBool, value) - _node.ContainsPasswds = value + if value, ok := lbc.mutation.ContainsPasswords(); ok { + _spec.SetField(localbreach.FieldContainsPasswords, field.TypeBool, value) + _node.ContainsPasswords = value } if value, ok := lbc.mutation.ContainsHashes(); ok { _spec.SetField(localbreach.FieldContainsHashes, field.TypeBool, value) @@ -319,6 +321,10 @@ func (lbc *LocalBreachCreate) createSpec() (*LocalBreach, *sqlgraph.CreateSpec) _spec.SetField(localbreach.FieldContainsEmails, field.TypeBool, value) _node.ContainsEmails = value } + if value, ok := lbc.mutation.ContainsUsernames(); ok { + _spec.SetField(localbreach.FieldContainsUsernames, field.TypeBool, value) + _node.ContainsUsernames = value + } if value, ok := lbc.mutation.HashType(); ok { _spec.SetField(localbreach.FieldHashType, field.TypeString, value) _node.HashType = &value @@ -332,8 +338,8 @@ func (lbc *LocalBreachCreate) createSpec() (*LocalBreach, *sqlgraph.CreateSpec) _node.HashPeppered = &value } if value, ok := lbc.mutation.Data(); ok { - _spec.SetField(localbreach.FieldData, field.TypeString, value) - _node.Data = &value + _spec.SetField(localbreach.FieldData, field.TypeJSON, value) + _node.Data = value } if value, ok := lbc.mutation.CreatedAt(); ok { _spec.SetField(localbreach.FieldCreatedAt, field.TypeTime, value) diff --git a/ent/localbreach_update.go b/ent/localbreach_update.go index e71ba2c..ca00c72 100644 --- a/ent/localbreach_update.go +++ b/ent/localbreach_update.go @@ -13,6 +13,7 @@ import ( "entgo.io/ent/schema/field" "git.dotya.ml/mirre-mt/pcmt/ent/localbreach" "git.dotya.ml/mirre-mt/pcmt/ent/predicate" + "git.dotya.ml/mirre-mt/pcmt/ent/schema" "git.dotya.ml/mirre-mt/pcmt/ent/trackedbreaches" "github.com/google/uuid" ) @@ -76,9 +77,9 @@ func (lbu *LocalBreachUpdate) SetIsVerified(b bool) *LocalBreachUpdate { return lbu } -// SetContainsPasswds sets the "contains_passwds" field. -func (lbu *LocalBreachUpdate) SetContainsPasswds(b bool) *LocalBreachUpdate { - lbu.mutation.SetContainsPasswds(b) +// SetContainsPasswords sets the "contains_passwords" field. +func (lbu *LocalBreachUpdate) SetContainsPasswords(b bool) *LocalBreachUpdate { + lbu.mutation.SetContainsPasswords(b) return lbu } @@ -94,6 +95,12 @@ func (lbu *LocalBreachUpdate) SetContainsEmails(b bool) *LocalBreachUpdate { return lbu } +// SetContainsUsernames sets the "contains_usernames" field. +func (lbu *LocalBreachUpdate) SetContainsUsernames(b bool) *LocalBreachUpdate { + lbu.mutation.SetContainsUsernames(b) + return lbu +} + // SetHashType sets the "hash_type" field. func (lbu *LocalBreachUpdate) SetHashType(s string) *LocalBreachUpdate { lbu.mutation.SetHashType(s) @@ -155,19 +162,11 @@ func (lbu *LocalBreachUpdate) ClearHashPeppered() *LocalBreachUpdate { } // SetData sets the "data" field. -func (lbu *LocalBreachUpdate) SetData(s string) *LocalBreachUpdate { +func (lbu *LocalBreachUpdate) SetData(s *schema.Data) *LocalBreachUpdate { lbu.mutation.SetData(s) return lbu } -// SetNillableData sets the "data" field if the given value is not nil. -func (lbu *LocalBreachUpdate) SetNillableData(s *string) *LocalBreachUpdate { - if s != nil { - lbu.SetData(*s) - } - return lbu -} - // ClearData clears the value of the "data" field. func (lbu *LocalBreachUpdate) ClearData() *LocalBreachUpdate { lbu.mutation.ClearData() @@ -279,8 +278,8 @@ func (lbu *LocalBreachUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := lbu.mutation.IsVerified(); ok { _spec.SetField(localbreach.FieldIsVerified, field.TypeBool, value) } - if value, ok := lbu.mutation.ContainsPasswds(); ok { - _spec.SetField(localbreach.FieldContainsPasswds, field.TypeBool, value) + if value, ok := lbu.mutation.ContainsPasswords(); ok { + _spec.SetField(localbreach.FieldContainsPasswords, field.TypeBool, value) } if value, ok := lbu.mutation.ContainsHashes(); ok { _spec.SetField(localbreach.FieldContainsHashes, field.TypeBool, value) @@ -288,6 +287,9 @@ func (lbu *LocalBreachUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := lbu.mutation.ContainsEmails(); ok { _spec.SetField(localbreach.FieldContainsEmails, field.TypeBool, value) } + if value, ok := lbu.mutation.ContainsUsernames(); ok { + _spec.SetField(localbreach.FieldContainsUsernames, field.TypeBool, value) + } if value, ok := lbu.mutation.HashType(); ok { _spec.SetField(localbreach.FieldHashType, field.TypeString, value) } @@ -307,10 +309,10 @@ func (lbu *LocalBreachUpdate) sqlSave(ctx context.Context) (n int, err error) { _spec.ClearField(localbreach.FieldHashPeppered, field.TypeBool) } if value, ok := lbu.mutation.Data(); ok { - _spec.SetField(localbreach.FieldData, field.TypeString, value) + _spec.SetField(localbreach.FieldData, field.TypeJSON, value) } if lbu.mutation.DataCleared() { - _spec.ClearField(localbreach.FieldData, field.TypeString) + _spec.ClearField(localbreach.FieldData, field.TypeJSON) } if lbu.mutation.TrackedBreachesCleared() { edge := &sqlgraph.EdgeSpec{ @@ -423,9 +425,9 @@ func (lbuo *LocalBreachUpdateOne) SetIsVerified(b bool) *LocalBreachUpdateOne { return lbuo } -// SetContainsPasswds sets the "contains_passwds" field. -func (lbuo *LocalBreachUpdateOne) SetContainsPasswds(b bool) *LocalBreachUpdateOne { - lbuo.mutation.SetContainsPasswds(b) +// SetContainsPasswords sets the "contains_passwords" field. +func (lbuo *LocalBreachUpdateOne) SetContainsPasswords(b bool) *LocalBreachUpdateOne { + lbuo.mutation.SetContainsPasswords(b) return lbuo } @@ -441,6 +443,12 @@ func (lbuo *LocalBreachUpdateOne) SetContainsEmails(b bool) *LocalBreachUpdateOn return lbuo } +// SetContainsUsernames sets the "contains_usernames" field. +func (lbuo *LocalBreachUpdateOne) SetContainsUsernames(b bool) *LocalBreachUpdateOne { + lbuo.mutation.SetContainsUsernames(b) + return lbuo +} + // SetHashType sets the "hash_type" field. func (lbuo *LocalBreachUpdateOne) SetHashType(s string) *LocalBreachUpdateOne { lbuo.mutation.SetHashType(s) @@ -502,19 +510,11 @@ func (lbuo *LocalBreachUpdateOne) ClearHashPeppered() *LocalBreachUpdateOne { } // SetData sets the "data" field. -func (lbuo *LocalBreachUpdateOne) SetData(s string) *LocalBreachUpdateOne { +func (lbuo *LocalBreachUpdateOne) SetData(s *schema.Data) *LocalBreachUpdateOne { lbuo.mutation.SetData(s) return lbuo } -// SetNillableData sets the "data" field if the given value is not nil. -func (lbuo *LocalBreachUpdateOne) SetNillableData(s *string) *LocalBreachUpdateOne { - if s != nil { - lbuo.SetData(*s) - } - return lbuo -} - // ClearData clears the value of the "data" field. func (lbuo *LocalBreachUpdateOne) ClearData() *LocalBreachUpdateOne { lbuo.mutation.ClearData() @@ -656,8 +656,8 @@ func (lbuo *LocalBreachUpdateOne) sqlSave(ctx context.Context) (_node *LocalBrea if value, ok := lbuo.mutation.IsVerified(); ok { _spec.SetField(localbreach.FieldIsVerified, field.TypeBool, value) } - if value, ok := lbuo.mutation.ContainsPasswds(); ok { - _spec.SetField(localbreach.FieldContainsPasswds, field.TypeBool, value) + if value, ok := lbuo.mutation.ContainsPasswords(); ok { + _spec.SetField(localbreach.FieldContainsPasswords, field.TypeBool, value) } if value, ok := lbuo.mutation.ContainsHashes(); ok { _spec.SetField(localbreach.FieldContainsHashes, field.TypeBool, value) @@ -665,6 +665,9 @@ func (lbuo *LocalBreachUpdateOne) sqlSave(ctx context.Context) (_node *LocalBrea if value, ok := lbuo.mutation.ContainsEmails(); ok { _spec.SetField(localbreach.FieldContainsEmails, field.TypeBool, value) } + if value, ok := lbuo.mutation.ContainsUsernames(); ok { + _spec.SetField(localbreach.FieldContainsUsernames, field.TypeBool, value) + } if value, ok := lbuo.mutation.HashType(); ok { _spec.SetField(localbreach.FieldHashType, field.TypeString, value) } @@ -684,10 +687,10 @@ func (lbuo *LocalBreachUpdateOne) sqlSave(ctx context.Context) (_node *LocalBrea _spec.ClearField(localbreach.FieldHashPeppered, field.TypeBool) } if value, ok := lbuo.mutation.Data(); ok { - _spec.SetField(localbreach.FieldData, field.TypeString, value) + _spec.SetField(localbreach.FieldData, field.TypeJSON, value) } if lbuo.mutation.DataCleared() { - _spec.ClearField(localbreach.FieldData, field.TypeString) + _spec.ClearField(localbreach.FieldData, field.TypeJSON) } if lbuo.mutation.TrackedBreachesCleared() { edge := &sqlgraph.EdgeSpec{ diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go index e8ea2b6..128c572 100644 --- a/ent/migrate/schema.go +++ b/ent/migrate/schema.go @@ -71,13 +71,14 @@ var ( {Name: "date", Type: field.TypeTime}, {Name: "description", Type: field.TypeString, Nullable: true}, {Name: "is_verified", Type: field.TypeBool}, - {Name: "contains_passwds", Type: field.TypeBool}, + {Name: "contains_passwords", Type: field.TypeBool}, {Name: "contains_hashes", Type: field.TypeBool}, {Name: "contains_emails", Type: field.TypeBool}, + {Name: "contains_usernames", Type: field.TypeBool}, {Name: "hash_type", Type: field.TypeString, Nullable: true}, {Name: "hash_salted", Type: field.TypeBool, Nullable: true}, {Name: "hash_peppered", Type: field.TypeBool, Nullable: true}, - {Name: "data", Type: field.TypeString, Nullable: true}, + {Name: "data", Type: field.TypeJSON, Nullable: true}, {Name: "created_at", Type: field.TypeTime}, } // LocalBreachesTable holds the schema information for the "local_breaches" table. diff --git a/ent/mutation.go b/ent/mutation.go index 554aea5..341d536 100644 --- a/ent/mutation.go +++ b/ent/mutation.go @@ -15,6 +15,7 @@ import ( "git.dotya.ml/mirre-mt/pcmt/ent/hibp" "git.dotya.ml/mirre-mt/pcmt/ent/localbreach" "git.dotya.ml/mirre-mt/pcmt/ent/predicate" + "git.dotya.ml/mirre-mt/pcmt/ent/schema" "git.dotya.ml/mirre-mt/pcmt/ent/searchquery" "git.dotya.ml/mirre-mt/pcmt/ent/settings" "git.dotya.ml/mirre-mt/pcmt/ent/setup" @@ -1860,13 +1861,14 @@ type LocalBreachMutation struct { date *time.Time description *string is_verified *bool - contains_passwds *bool + contains_passwords *bool contains_hashes *bool contains_emails *bool + contains_usernames *bool hash_type *string hash_salted *bool hash_peppered *bool - data *string + data **schema.Data created_at *time.Time clearedFields map[string]struct{} tracked_breaches map[uuid.UUID]struct{} @@ -2138,40 +2140,40 @@ func (m *LocalBreachMutation) ResetIsVerified() { m.is_verified = nil } -// SetContainsPasswds sets the "contains_passwds" field. -func (m *LocalBreachMutation) SetContainsPasswds(b bool) { - m.contains_passwds = &b +// SetContainsPasswords sets the "contains_passwords" field. +func (m *LocalBreachMutation) SetContainsPasswords(b bool) { + m.contains_passwords = &b } -// ContainsPasswds returns the value of the "contains_passwds" field in the mutation. -func (m *LocalBreachMutation) ContainsPasswds() (r bool, exists bool) { - v := m.contains_passwds +// ContainsPasswords returns the value of the "contains_passwords" field in the mutation. +func (m *LocalBreachMutation) ContainsPasswords() (r bool, exists bool) { + v := m.contains_passwords if v == nil { return } return *v, true } -// OldContainsPasswds returns the old "contains_passwds" field's value of the LocalBreach entity. +// OldContainsPasswords returns the old "contains_passwords" field's value of the LocalBreach entity. // If the LocalBreach object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *LocalBreachMutation) OldContainsPasswds(ctx context.Context) (v bool, err error) { +func (m *LocalBreachMutation) OldContainsPasswords(ctx context.Context) (v bool, err error) { if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldContainsPasswds is only allowed on UpdateOne operations") + return v, errors.New("OldContainsPasswords is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { - return v, errors.New("OldContainsPasswds requires an ID field in the mutation") + return v, errors.New("OldContainsPasswords requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { - return v, fmt.Errorf("querying old value for OldContainsPasswds: %w", err) + return v, fmt.Errorf("querying old value for OldContainsPasswords: %w", err) } - return oldValue.ContainsPasswds, nil + return oldValue.ContainsPasswords, nil } -// ResetContainsPasswds resets all changes to the "contains_passwds" field. -func (m *LocalBreachMutation) ResetContainsPasswds() { - m.contains_passwds = nil +// ResetContainsPasswords resets all changes to the "contains_passwords" field. +func (m *LocalBreachMutation) ResetContainsPasswords() { + m.contains_passwords = nil } // SetContainsHashes sets the "contains_hashes" field. @@ -2246,6 +2248,42 @@ func (m *LocalBreachMutation) ResetContainsEmails() { m.contains_emails = nil } +// SetContainsUsernames sets the "contains_usernames" field. +func (m *LocalBreachMutation) SetContainsUsernames(b bool) { + m.contains_usernames = &b +} + +// ContainsUsernames returns the value of the "contains_usernames" field in the mutation. +func (m *LocalBreachMutation) ContainsUsernames() (r bool, exists bool) { + v := m.contains_usernames + if v == nil { + return + } + return *v, true +} + +// OldContainsUsernames returns the old "contains_usernames" field's value of the LocalBreach entity. +// If the LocalBreach object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *LocalBreachMutation) OldContainsUsernames(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldContainsUsernames is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldContainsUsernames requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldContainsUsernames: %w", err) + } + return oldValue.ContainsUsernames, nil +} + +// ResetContainsUsernames resets all changes to the "contains_usernames" field. +func (m *LocalBreachMutation) ResetContainsUsernames() { + m.contains_usernames = nil +} + // SetHashType sets the "hash_type" field. func (m *LocalBreachMutation) SetHashType(s string) { m.hash_type = &s @@ -2394,12 +2432,12 @@ func (m *LocalBreachMutation) ResetHashPeppered() { } // SetData sets the "data" field. -func (m *LocalBreachMutation) SetData(s string) { +func (m *LocalBreachMutation) SetData(s *schema.Data) { m.data = &s } // Data returns the value of the "data" field in the mutation. -func (m *LocalBreachMutation) Data() (r string, exists bool) { +func (m *LocalBreachMutation) Data() (r *schema.Data, exists bool) { v := m.data if v == nil { return @@ -2410,7 +2448,7 @@ func (m *LocalBreachMutation) Data() (r string, exists bool) { // OldData returns the old "data" field's value of the LocalBreach entity. // If the LocalBreach object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *LocalBreachMutation) OldData(ctx context.Context) (v *string, err error) { +func (m *LocalBreachMutation) OldData(ctx context.Context) (v *schema.Data, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldData is only allowed on UpdateOne operations") } @@ -2566,7 +2604,7 @@ func (m *LocalBreachMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *LocalBreachMutation) Fields() []string { - fields := make([]string, 0, 12) + fields := make([]string, 0, 13) if m.name != nil { fields = append(fields, localbreach.FieldName) } @@ -2579,8 +2617,8 @@ func (m *LocalBreachMutation) Fields() []string { if m.is_verified != nil { fields = append(fields, localbreach.FieldIsVerified) } - if m.contains_passwds != nil { - fields = append(fields, localbreach.FieldContainsPasswds) + if m.contains_passwords != nil { + fields = append(fields, localbreach.FieldContainsPasswords) } if m.contains_hashes != nil { fields = append(fields, localbreach.FieldContainsHashes) @@ -2588,6 +2626,9 @@ func (m *LocalBreachMutation) Fields() []string { if m.contains_emails != nil { fields = append(fields, localbreach.FieldContainsEmails) } + if m.contains_usernames != nil { + fields = append(fields, localbreach.FieldContainsUsernames) + } if m.hash_type != nil { fields = append(fields, localbreach.FieldHashType) } @@ -2619,12 +2660,14 @@ func (m *LocalBreachMutation) Field(name string) (ent.Value, bool) { return m.Description() case localbreach.FieldIsVerified: return m.IsVerified() - case localbreach.FieldContainsPasswds: - return m.ContainsPasswds() + case localbreach.FieldContainsPasswords: + return m.ContainsPasswords() case localbreach.FieldContainsHashes: return m.ContainsHashes() case localbreach.FieldContainsEmails: return m.ContainsEmails() + case localbreach.FieldContainsUsernames: + return m.ContainsUsernames() case localbreach.FieldHashType: return m.HashType() case localbreach.FieldHashSalted: @@ -2652,12 +2695,14 @@ func (m *LocalBreachMutation) OldField(ctx context.Context, name string) (ent.Va return m.OldDescription(ctx) case localbreach.FieldIsVerified: return m.OldIsVerified(ctx) - case localbreach.FieldContainsPasswds: - return m.OldContainsPasswds(ctx) + case localbreach.FieldContainsPasswords: + return m.OldContainsPasswords(ctx) case localbreach.FieldContainsHashes: return m.OldContainsHashes(ctx) case localbreach.FieldContainsEmails: return m.OldContainsEmails(ctx) + case localbreach.FieldContainsUsernames: + return m.OldContainsUsernames(ctx) case localbreach.FieldHashType: return m.OldHashType(ctx) case localbreach.FieldHashSalted: @@ -2705,12 +2750,12 @@ func (m *LocalBreachMutation) SetField(name string, value ent.Value) error { } m.SetIsVerified(v) return nil - case localbreach.FieldContainsPasswds: + case localbreach.FieldContainsPasswords: v, ok := value.(bool) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } - m.SetContainsPasswds(v) + m.SetContainsPasswords(v) return nil case localbreach.FieldContainsHashes: v, ok := value.(bool) @@ -2726,6 +2771,13 @@ func (m *LocalBreachMutation) SetField(name string, value ent.Value) error { } m.SetContainsEmails(v) return nil + case localbreach.FieldContainsUsernames: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetContainsUsernames(v) + return nil case localbreach.FieldHashType: v, ok := value.(string) if !ok { @@ -2748,7 +2800,7 @@ func (m *LocalBreachMutation) SetField(name string, value ent.Value) error { m.SetHashPeppered(v) return nil case localbreach.FieldData: - v, ok := value.(string) + v, ok := value.(*schema.Data) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } @@ -2855,8 +2907,8 @@ func (m *LocalBreachMutation) ResetField(name string) error { case localbreach.FieldIsVerified: m.ResetIsVerified() return nil - case localbreach.FieldContainsPasswds: - m.ResetContainsPasswds() + case localbreach.FieldContainsPasswords: + m.ResetContainsPasswords() return nil case localbreach.FieldContainsHashes: m.ResetContainsHashes() @@ -2864,6 +2916,9 @@ func (m *LocalBreachMutation) ResetField(name string) error { case localbreach.FieldContainsEmails: m.ResetContainsEmails() return nil + case localbreach.FieldContainsUsernames: + m.ResetContainsUsernames() + return nil case localbreach.FieldHashType: m.ResetHashType() return nil diff --git a/ent/runtime.go b/ent/runtime.go index c490e8c..91ba5c2 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -76,7 +76,7 @@ func init() { // localbreach.DefaultDate holds the default value on creation for the date field. localbreach.DefaultDate = localbreachDescDate.Default.(time.Time) // localbreachDescCreatedAt is the schema descriptor for created_at field. - localbreachDescCreatedAt := localbreachFields[12].Descriptor() + localbreachDescCreatedAt := localbreachFields[13].Descriptor() // localbreach.DefaultCreatedAt holds the default value on creation for the created_at field. localbreach.DefaultCreatedAt = localbreachDescCreatedAt.Default.(time.Time) // localbreachDescID is the schema descriptor for id field. diff --git a/ent/schema/localbreach.go b/ent/schema/localbreach.go index 7a89ecb..60248aa 100644 --- a/ent/schema/localbreach.go +++ b/ent/schema/localbreach.go @@ -17,6 +17,36 @@ type LocalBreach struct { ent.Schema } +// ImportSchema is the LocalBreach model. +type ImportSchema struct { + Name string `yaml:"name" validate:"required,name"` + Description string `yaml:"description"` + CreatedAt time.Time `yaml:"createdAt"` + Date time.Time `yaml:"time"` + IsVerified bool `yaml:"isVerified"` + ContainsUsernames bool `yaml:"containsUsernames"` + ContainsEmails bool `yaml:"containsEmails"` + ContainsPasswords bool `yaml:"containsPasswds"` + ContainsHashes bool `yaml:"containsHashes"` + HashType string `yaml:"hashType"` + HashSalted bool `yaml:"hashSalted"` + HashPeppered bool `yaml:"hashPeppered"` + Data Data `yaml:"data"` +} + +type ( + DataUsernames []string + DataEmails []string + DataHashes []string + DataPasswords []string + Data struct { + Usernames *DataUsernames + Emails *DataEmails + Hashes *DataHashes + Passwords *DataPasswords + } +) + // Fields of the LocalBreach. func (LocalBreach) Fields() []ent.Field { return []ent.Field{ @@ -34,9 +64,10 @@ func (LocalBreach) Fields() []ent.Field { Optional(). Nillable(), field.Bool("is_verified"), - field.Bool("contains_passwds"), + field.Bool("contains_passwords"), field.Bool("contains_hashes"), field.Bool("contains_emails"), + field.Bool("contains_usernames"), field.String("hash_type"). Comment("MD5, SHA1, Argon2id..."). Optional(). @@ -47,9 +78,8 @@ func (LocalBreach) Fields() []ent.Field { field.Bool("hash_peppered"). Optional(). Nillable(), - field.String("data"). - Optional(). - Nillable(), + field.JSON("data", &Data{}). + Optional(), field.Time("created_at"). Default(time.Now()). Immutable(), diff --git a/modules/localbreach/breach.go b/modules/localbreach/breach.go index a7c5826..ec1c963 100644 --- a/modules/localbreach/breach.go +++ b/modules/localbreach/breach.go @@ -5,29 +5,23 @@ package localbreach import ( "bytes" + "context" "io" "os" - "time" + "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 BreachDataSchema struct { - Name string `yaml:"name" validate:"required,name"` - Time time.Time `yaml:"time"` - IsVerified bool `yaml:"isVerified"` - ContainsPasswords bool `yaml:"containsPasswds"` - ContainsHashes bool `yaml:"containsHashes"` - HashType string `yaml:"hashType"` - HashSalted bool `yaml:"hashSalted"` - HashPeppered bool `yaml:"hashPeppered"` - ContainsUsernames bool `yaml:"containsUsernames"` - ContainsEmails bool `yaml:"containsEmails"` - Data any `yaml:"data"` -} +type CtxKey struct{} -// Load loads local breach data. -func Load(path string) (*[]BreachDataSchema, error) { +// 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 @@ -41,15 +35,15 @@ func Load(path string) (*[]BreachDataSchema, error) { return lb, nil } -func loadLocalBreach(b []byte) (*[]BreachDataSchema, error) { +func loadLocalBreach(b []byte) (*[]schema.ImportSchema, error) { r := bytes.NewReader(b) decoder := yaml.NewDecoder(r) - lb := make([]BreachDataSchema, 0) + lb := make([]schema.ImportSchema, 0) - var bds BreachDataSchema + var is schema.ImportSchema for { - if err := decoder.Decode(&bds); err != nil { + if err := decoder.Decode(&is); err != nil { if err != io.EOF { return nil, err } @@ -57,8 +51,60 @@ func loadLocalBreach(b []byte) (*[]BreachDataSchema, error) { break // get out when there are no more documents to read. } - lb = append(lb, bds) + 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 +} diff --git a/run.go b/run.go index e3c5a34..59d6dd8 100644 --- a/run.go +++ b/run.go @@ -208,8 +208,16 @@ func run() error { //nolint:gocognit return err } + if _, err = localbreach.ImportLocalBreach( + context.WithValue( + context.Background(), localbreach.CtxKey{}, slogger), + db, lb, + ); err != nil { + return err + } + log.Infof("Import succeeded: %+v", lb) - fmt.Fprint(os.Stdout, "\033[32m🗸\033[0m Import succeeded \n") + fmt.Fprint(os.Stdout, "\033[32m✓\033[0m Import succeeded \n") return nil }