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