github.com/merlinepedra/gophish1@v0.9.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 } else { 50 // If the user chooses to re-enable the capture passwords setting, 51 // we need to re-add the name attribute 52 inputs := f.Find("input") 53 inputs.Each(func(j int, input *goquery.Selection) { 54 if t, _ := input.Attr("type"); strings.EqualFold(t, "password") { 55 input.SetAttr("name", "password") 56 } 57 }) 58 } 59 } else { 60 // Otherwise, remove the name from all 61 // inputs. 62 inputFields := f.Find("input") 63 inputFields.Each(func(j int, input *goquery.Selection) { 64 input.RemoveAttr("name") 65 }) 66 } 67 }) 68 p.HTML, err = d.Html() 69 return err 70 } 71 72 // Validate ensures that a page contains the appropriate details 73 func (p *Page) Validate() error { 74 if p.Name == "" { 75 return ErrPageNameNotSpecified 76 } 77 // If the user specifies to capture passwords, 78 // we automatically capture credentials 79 if p.CapturePasswords && !p.CaptureCredentials { 80 p.CaptureCredentials = true 81 } 82 if err := ValidateTemplate(p.HTML); err != nil { 83 return err 84 } 85 if err := ValidateTemplate(p.RedirectURL); err != nil { 86 return err 87 } 88 return p.parseHTML() 89 } 90 91 // GetPages returns the pages owned by the given user. 92 func GetPages(uid int64) ([]Page, error) { 93 ps := []Page{} 94 err := db.Where("user_id=?", uid).Find(&ps).Error 95 if err != nil { 96 log.Error(err) 97 return ps, err 98 } 99 return ps, err 100 } 101 102 // GetPage returns the page, if it exists, specified by the given id and user_id. 103 func GetPage(id int64, uid int64) (Page, error) { 104 p := Page{} 105 err := db.Where("user_id=? and id=?", uid, id).Find(&p).Error 106 if err != nil { 107 log.Error(err) 108 } 109 return p, err 110 } 111 112 // GetPageByName returns the page, if it exists, specified by the given name and user_id. 113 func GetPageByName(n string, uid int64) (Page, error) { 114 p := Page{} 115 err := db.Where("user_id=? and name=?", uid, n).Find(&p).Error 116 if err != nil { 117 log.Error(err) 118 } 119 return p, err 120 } 121 122 // PostPage creates a new page in the database. 123 func PostPage(p *Page) error { 124 err := p.Validate() 125 if err != nil { 126 log.Error(err) 127 return err 128 } 129 // Insert into the DB 130 err = db.Save(p).Error 131 if err != nil { 132 log.Error(err) 133 } 134 return err 135 } 136 137 // PutPage edits an existing Page in the database. 138 // Per the PUT Method RFC, it presumes all data for a page is provided. 139 func PutPage(p *Page) error { 140 err := p.Validate() 141 err = db.Where("id=?", p.Id).Save(p).Error 142 if err != nil { 143 log.Error(err) 144 } 145 return err 146 } 147 148 // DeletePage deletes an existing page in the database. 149 // An error is returned if a page with the given user id and page id is not found. 150 func DeletePage(id int64, uid int64) error { 151 err := db.Where("user_id=?", uid).Delete(Page{Id: id}).Error 152 if err != nil { 153 log.Error(err) 154 } 155 return err 156 }