A More Secure Internet Connection for Your Home https://fen.gg
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

159 lines
3.9 KiB

  1. package model
  2. //
  3. // Fengg Security Gateway Server Application
  4. // Copyright (C) 2020 Lukas Matt <support@fen.gg>
  5. //
  6. // This program is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. //
  18. import (
  19. "time"
  20. "fmt"
  21. "github.com/jmoiron/sqlx"
  22. _ "github.com/lib/pq"
  23. )
  24. const (
  25. ProfileNamedInsertTmpl = `
  26. INSERT INTO profiles (
  27. created_at, updated_at, ip_information_id, anomaly_detection
  28. ) VALUES (
  29. now(), now(), :ip_information_id, :anomaly_detection
  30. ) RETURNING id;`
  31. ProfileNamedUpdateTmpl = `
  32. UPDATE profiles
  33. SET updated_at=now(), anomaly_detection=:anomaly_detection
  34. WHERE id=:id
  35. OR ip_information_id=:ip_information_id;`
  36. ProfileQueryTmpl = `SELECT * FROM profiles %s;`
  37. )
  38. type Profile struct {
  39. ID uint `db:"id" json:"id"`
  40. CreatedAt time.Time `db:"created_at" json:"createdAt"`
  41. UpdatedAt time.Time `db:"updated_at" json:"updatedAt"`
  42. IPInformationID uint `db:"ip_information_id" json:"ipInformationId"`
  43. IPInformation IPInformation `db:"-" json:"ipInformation"`
  44. AnomalyDetection float64 `db:"anomaly_detection" json:"anomalyDetection"`
  45. }
  46. type Profiles []Profile
  47. func NewProfile() *Profile {
  48. return &Profile{
  49. CreatedAt: time.Now(),
  50. UpdatedAt: time.Now(),
  51. }
  52. }
  53. func (profiles Profiles) PreLoad() error {
  54. for _, profile := range profiles {
  55. err := profile.PreLoad()
  56. if err != nil {
  57. return err
  58. }
  59. }
  60. return nil
  61. }
  62. func (profiles *Profiles) FindAll() error {
  63. db, err := sqlx.Connect(dbDriver, dbConnect)
  64. if err != nil {
  65. return err
  66. }
  67. defer db.Close()
  68. err = db.Select(profiles, fmt.Sprintf(ProfileQueryTmpl, ""))
  69. if err != nil {
  70. return err
  71. }
  72. return profiles.PreLoad()
  73. }
  74. // PreLoad will fetch all extra information like e.g.
  75. // IP information and write them to the profile struct
  76. func (profile *Profile) PreLoad() error {
  77. profile.IPInformation.ID = profile.IPInformationID
  78. err := profile.IPInformation.Find()
  79. if err != nil {
  80. return err
  81. }
  82. // if all IDs are zero the Find function can
  83. // try looking for a record via the IP address
  84. // or in case of a protocol the name attribute.
  85. // Then we have the actually ID of the record
  86. // within the nested struct which we should populate
  87. // to the actual connection struct.
  88. profile.IPInformationID = profile.IPInformation.ID
  89. return nil
  90. }
  91. func (profile *Profile) Create() error {
  92. db, err := sqlx.Connect(dbDriver, dbConnect)
  93. if err != nil {
  94. return err
  95. }
  96. defer db.Close()
  97. rows, err := db.NamedQuery(ProfileNamedInsertTmpl, profile)
  98. if err != nil {
  99. return err
  100. }
  101. defer rows.Close()
  102. for rows.Next() {
  103. err = rows.Scan(&profile.ID)
  104. if err != nil {
  105. return err
  106. }
  107. }
  108. return nil
  109. }
  110. func (profile *Profile) Exists() bool {
  111. db, err := sqlx.Connect(dbDriver, dbConnect)
  112. if err != nil {
  113. logger.Error().Err(err).Msg("cannot connect to database")
  114. return false
  115. }
  116. defer db.Close()
  117. err = db.Get(profile,
  118. fmt.Sprintf(ProfileQueryTmpl, `WHERE p.id=$1 OR p.ip_information_id=$2`),
  119. profile.ID, profile.IPInformation.ID,
  120. ); if err != nil {
  121. return true
  122. }
  123. err = profile.PreLoad()
  124. if err != nil {
  125. logger.Warn().Err(err).Msg("cannot load extra information in profile struct")
  126. }
  127. return true
  128. }
  129. func (profile *Profile) Update() error {
  130. db, err := sqlx.Connect(dbDriver, dbConnect)
  131. if err != nil {
  132. return err
  133. }
  134. defer db.Close()
  135. _, err = db.NamedExec(ProfileNamedUpdateTmpl, profile)
  136. return err
  137. }