🎣 Open-Source Phishing Toolkit
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.

184 lines
4.7 KiB

  1. package models
  2. import (
  3. "errors"
  4. "time"
  5. log "github.com/gophish/gophish/logger"
  6. "github.com/jinzhu/gorm"
  7. )
  8. // Template models hold the attributes for an email template to be sent to targets
  9. type Template struct {
  10. Id int64 `json:"id" gorm:"column:id; primary_key:yes"`
  11. UserId int64 `json:"-" gorm:"column:user_id"`
  12. Name string `json:"name"`
  13. Subject string `json:"subject"`
  14. Text string `json:"text"`
  15. HTML string `json:"html" gorm:"column:html"`
  16. ModifiedDate time.Time `json:"modified_date"`
  17. Attachments []Attachment `json:"attachments"`
  18. }
  19. // ErrTemplateNameNotSpecified is thrown when a template name is not specified
  20. var ErrTemplateNameNotSpecified = errors.New("Template name not specified")
  21. // ErrTemplateMissingParameter is thrown when a needed parameter is not provided
  22. var ErrTemplateMissingParameter = errors.New("Need to specify at least plaintext or HTML content")
  23. // Validate checks the given template to make sure values are appropriate and complete
  24. func (t *Template) Validate() error {
  25. switch {
  26. case t.Name == "":
  27. return ErrTemplateNameNotSpecified
  28. case t.Text == "" && t.HTML == "":
  29. return ErrTemplateMissingParameter
  30. }
  31. if err := ValidateTemplate(t.HTML); err != nil {
  32. return err
  33. }
  34. if err := ValidateTemplate(t.Text); err != nil {
  35. return err
  36. }
  37. return nil
  38. }
  39. // GetTemplates returns the templates owned by the given user.
  40. func GetTemplates(uid int64) ([]Template, error) {
  41. ts := []Template{}
  42. err := db.Where("user_id=?", uid).Find(&ts).Error
  43. if err != nil {
  44. log.Error(err)
  45. return ts, err
  46. }
  47. for i := range ts {
  48. // Get Attachments
  49. err = db.Where("template_id=?", ts[i].Id).Find(&ts[i].Attachments).Error
  50. if err == nil && len(ts[i].Attachments) == 0 {
  51. ts[i].Attachments = make([]Attachment, 0)
  52. }
  53. if err != nil && err != gorm.ErrRecordNotFound {
  54. log.Error(err)
  55. return ts, err
  56. }
  57. }
  58. return ts, err
  59. }
  60. // GetTemplate returns the template, if it exists, specified by the given id and user_id.
  61. func GetTemplate(id int64, uid int64) (Template, error) {
  62. t := Template{}
  63. err := db.Where("user_id=? and id=?", uid, id).Find(&t).Error
  64. if err != nil {
  65. log.Error(err)
  66. return t, err
  67. }
  68. // Get Attachments
  69. err = db.Where("template_id=?", t.Id).Find(&t.Attachments).Error
  70. if err != nil && err != gorm.ErrRecordNotFound {
  71. log.Error(err)
  72. return t, err
  73. }
  74. if err == nil && len(t.Attachments) == 0 {
  75. t.Attachments = make([]Attachment, 0)
  76. }
  77. return t, err
  78. }
  79. // GetTemplateByName returns the template, if it exists, specified by the given name and user_id.
  80. func GetTemplateByName(n string, uid int64) (Template, error) {
  81. t := Template{}
  82. err := db.Where("user_id=? and name=?", uid, n).Find(&t).Error
  83. if err != nil {
  84. log.Error(err)
  85. return t, err
  86. }
  87. // Get Attachments
  88. err = db.Where("template_id=?", t.Id).Find(&t.Attachments).Error
  89. if err != nil && err != gorm.ErrRecordNotFound {
  90. log.Error(err)
  91. return t, err
  92. }
  93. if err == nil && len(t.Attachments) == 0 {
  94. t.Attachments = make([]Attachment, 0)
  95. }
  96. return t, err
  97. }
  98. // PostTemplate creates a new template in the database.
  99. func PostTemplate(t *Template) error {
  100. // Insert into the DB
  101. if err := t.Validate(); err != nil {
  102. return err
  103. }
  104. err := db.Save(t).Error
  105. if err != nil {
  106. log.Error(err)
  107. return err
  108. }
  109. // Save every attachment
  110. for i := range t.Attachments {
  111. t.Attachments[i].TemplateId = t.Id
  112. err := db.Save(&t.Attachments[i]).Error
  113. if err != nil {
  114. log.Error(err)
  115. return err
  116. }
  117. }
  118. return nil
  119. }
  120. // PutTemplate edits an existing template in the database.
  121. // Per the PUT Method RFC, it presumes all data for a template is provided.
  122. func PutTemplate(t *Template) error {
  123. if err := t.Validate(); err != nil {
  124. return err
  125. }
  126. // Delete all attachments, and replace with new ones
  127. err := db.Where("template_id=?", t.Id).Delete(&Attachment{}).Error
  128. if err != nil && err != gorm.ErrRecordNotFound {
  129. log.Error(err)
  130. return err
  131. }
  132. if err == gorm.ErrRecordNotFound {
  133. err = nil
  134. }
  135. for i := range t.Attachments {
  136. t.Attachments[i].TemplateId = t.Id
  137. err := db.Save(&t.Attachments[i]).Error
  138. if err != nil {
  139. log.Error(err)
  140. return err
  141. }
  142. }
  143. // Save final template
  144. err = db.Where("id=?", t.Id).Save(t).Error
  145. if err != nil {
  146. log.Error(err)
  147. return err
  148. }
  149. return nil
  150. }
  151. // DeleteTemplate deletes an existing template in the database.
  152. // An error is returned if a template with the given user id and template id is not found.
  153. func DeleteTemplate(id int64, uid int64) error {
  154. // Delete attachments
  155. err := db.Where("template_id=?", id).Delete(&Attachment{}).Error
  156. if err != nil {
  157. log.Error(err)
  158. return err
  159. }
  160. // Finally, delete the template itself
  161. err = db.Where("user_id=?", uid).Delete(Template{Id: id}).Error
  162. if err != nil {
  163. log.Error(err)
  164. return err
  165. }
  166. return nil
  167. }