github.com/glennzw/gophish@v0.8.1-0.20190824020715-24fe998a3aa0/models/template_context.go (about) 1 package models 2 3 import ( 4 "bytes" 5 "net/mail" 6 "net/url" 7 "path" 8 "text/template" 9 ) 10 11 // TemplateContext is an interface that allows both campaigns and email 12 // requests to have a PhishingTemplateContext generated for them. 13 type TemplateContext interface { 14 getFromAddress() string 15 getBaseURL() string 16 } 17 18 // PhishingTemplateContext is the context that is sent to any template, such 19 // as the email or landing page content. 20 type PhishingTemplateContext struct { 21 From string 22 URL string 23 Tracker string 24 TrackingURL string 25 RId string 26 BaseURL string 27 BaseRecipient 28 } 29 30 // NewPhishingTemplateContext returns a populated PhishingTemplateContext, 31 // parsing the correct fields from the provided TemplateContext and recipient. 32 func NewPhishingTemplateContext(ctx TemplateContext, r BaseRecipient, rid string) (PhishingTemplateContext, error) { 33 f, err := mail.ParseAddress(ctx.getFromAddress()) 34 if err != nil { 35 return PhishingTemplateContext{}, err 36 } 37 fn := f.Name 38 if fn == "" { 39 fn = f.Address 40 } 41 templateURL, err := ExecuteTemplate(ctx.getBaseURL(), r) 42 if err != nil { 43 return PhishingTemplateContext{}, err 44 } 45 46 // For the base URL, we'll reset the the path and the query 47 // This will create a URL in the form of http://example.com 48 baseURL, _ := url.Parse(templateURL) 49 baseURL.Path = "" 50 baseURL.RawQuery = "" 51 52 phishURL, _ := url.Parse(templateURL) 53 q := phishURL.Query() 54 q.Set(RecipientParameter, rid) 55 phishURL.RawQuery = q.Encode() 56 57 trackingURL, _ := url.Parse(templateURL) 58 trackingURL.Path = path.Join(trackingURL.Path, "/track") 59 trackingURL.RawQuery = q.Encode() 60 61 return PhishingTemplateContext{ 62 BaseRecipient: r, 63 BaseURL: baseURL.String(), 64 URL: phishURL.String(), 65 TrackingURL: trackingURL.String(), 66 Tracker: "<img alt='' style='display: none' src='" + trackingURL.String() + "'/>", 67 From: fn, 68 RId: rid, 69 }, nil 70 } 71 72 // ExecuteTemplate creates a templated string based on the provided 73 // template body and data. 74 func ExecuteTemplate(text string, data interface{}) (string, error) { 75 buff := bytes.Buffer{} 76 tmpl, err := template.New("template").Parse(text) 77 if err != nil { 78 return buff.String(), err 79 } 80 err = tmpl.Execute(&buff, data) 81 return buff.String(), err 82 } 83 84 // ValidationContext is used for validating templates and pages 85 type ValidationContext struct { 86 FromAddress string 87 BaseURL string 88 } 89 90 func (vc ValidationContext) getFromAddress() string { 91 return vc.FromAddress 92 } 93 94 func (vc ValidationContext) getBaseURL() string { 95 return vc.BaseURL 96 } 97 98 // ValidateTemplate ensures that the provided text in the page or template 99 // uses the supported template variables correctly. 100 func ValidateTemplate(text string) error { 101 vc := ValidationContext{ 102 FromAddress: "foo@bar.com", 103 BaseURL: "http://example.com", 104 } 105 td := Result{ 106 BaseRecipient: BaseRecipient{ 107 Email: "foo@bar.com", 108 FirstName: "Foo", 109 LastName: "Bar", 110 Position: "Test", 111 }, 112 RId: "123456", 113 } 114 ptx, err := NewPhishingTemplateContext(vc, td.BaseRecipient, td.RId) 115 if err != nil { 116 return err 117 } 118 _, err = ExecuteTemplate(text, ptx) 119 if err != nil { 120 return err 121 } 122 return nil 123 }