github.com/topsteplocal/gophish@v0.6.0/models/page.go (about) 1 package models 2 3 import ( 4 "errors" 5 "strings" 6 "time" 7 8 "github.com/PuerkitoBio/goquery" 9 log "github.com/gophish/gophish/logger" 10 ) 11 12 // Page contains the fields used for a Page model 13 type Page 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 HTML string `json:"html" gorm:"column:html"` 18 CaptureCredentials bool `json:"capture_credentials" gorm:"column:capture_credentials"` 19 CapturePasswords bool `json:"capture_passwords" gorm:"column:capture_passwords"` 20 RedirectURL string `json:"redirect_url" gorm:"column:redirect_url"` 21 ModifiedDate time.Time `json:"modified_date"` 22 } 23 24 // ErrPageNameNotSpecified is thrown if the name of the landing page is blank. 25 var ErrPageNameNotSpecified = errors.New("Page Name not specified") 26 27 // parseHTML parses the page HTML on save to handle the 28 // capturing (or lack thereof!) of credentials and passwords 29 func (p *Page) parseHTML() error { 30 d, err := goquery.NewDocumentFromReader(strings.NewReader(p.HTML)) 31 if err != nil { 32 return err 33 } 34 forms := d.Find("form") 35 forms.Each(func(i int, f *goquery.Selection) { 36 // We always want the submitted events to be 37 // sent to our server 38 f.SetAttr("action", "") 39 if p.CaptureCredentials { 40 // If we don't want to capture passwords, 41 // find all the password fields and remove the "name" attribute. 42 if !p.CapturePasswords { 43 inputs := f.Find("input") 44 inputs.Each(func(j int, input *goquery.Selection) { 45 if t, _ := input.Attr("type"); strings.EqualFold(t, "password") { 46 input.RemoveAttr("name") 47 } 48 }) 49 } 50 } else { 51 // Otherwise, remove the name from all 52 // inputs. 53 inputFields := f.Find("input") 54 inputFields.Each(func(j int, input *goquery.Selection) { 55 input.RemoveAttr("name") 56 }) 57 } 58 }) 59 p.HTML, err = d.Html() 60 return err 61 } 62 63 // Validate ensures that a page contains the appropriate details 64 func (p *Page) Validate() error { 65 if p.Name == "" { 66 return ErrPageNameNotSpecified 67 } 68 // If the user specifies to capture passwords, 69 // we automatically capture credentials 70 if p.CapturePasswords && !p.CaptureCredentials { 71 p.CaptureCredentials = true 72 } 73 return p.parseHTML() 74 } 75 76 // GetPages returns the pages owned by the given user. 77 func GetPages(uid int64) ([]Page, error) { 78 ps := []Page{} 79 err := db.Where("user_id=?", uid).Find(&ps).Error 80 if err != nil { 81 log.Error(err) 82 return ps, err 83 } 84 return ps, err 85 } 86 87 // GetPage returns the page, if it exists, specified by the given id and user_id. 88 func GetPage(id int64, uid int64) (Page, error) { 89 p := Page{} 90 err := db.Where("user_id=? and id=?", uid, id).Find(&p).Error 91 if err != nil { 92 log.Error(err) 93 } 94 return p, err 95 } 96 97 // GetPageByName returns the page, if it exists, specified by the given name and user_id. 98 func GetPageByName(n string, uid int64) (Page, error) { 99 p := Page{} 100 err := db.Where("user_id=? and name=?", uid, n).Find(&p).Error 101 if err != nil { 102 log.Error(err) 103 } 104 return p, err 105 } 106 107 // PostPage creates a new page in the database. 108 func PostPage(p *Page) error { 109 err := p.Validate() 110 if err != nil { 111 log.Error(err) 112 return err 113 } 114 // Insert into the DB 115 err = db.Save(p).Error 116 if err != nil { 117 log.Error(err) 118 } 119 return err 120 } 121 122 // PutPage edits an existing Page in the database. 123 // Per the PUT Method RFC, it presumes all data for a page is provided. 124 func PutPage(p *Page) error { 125 err := p.Validate() 126 err = db.Where("id=?", p.Id).Save(p).Error 127 if err != nil { 128 log.Error(err) 129 } 130 return err 131 } 132 133 // DeletePage deletes an existing page in the database. 134 // An error is returned if a page with the given user id and page id is not found. 135 func DeletePage(id int64, uid int64) error { 136 err = db.Where("user_id=?", uid).Delete(Page{Id: id}).Error 137 if err != nil { 138 log.Error(err) 139 } 140 return err 141 }