package models import ( "bytes" "net/mail" "net/url" "path" "text/template" ) // TemplateContext is an interface that allows both campaigns and email // requests to have a PhishingTemplateContext generated for them. type TemplateContext interface { getFromAddress() string getBaseURL() string } // PhishingTemplateContext is the context that is sent to any template, such // as the email or landing page content. type PhishingTemplateContext struct { From string URL string Tracker string TrackingURL string RId string BaseRecipient } // NewPhishingTemplateContext returns a populated PhishingTemplateContext, // parsing the correct fields from the provided TemplateContext and recipient. func NewPhishingTemplateContext(ctx TemplateContext, r BaseRecipient, rid string) (PhishingTemplateContext, error) { f, err := mail.ParseAddress(ctx.getFromAddress()) if err != nil { return PhishingTemplateContext{}, err } fn := f.Name if fn == "" { fn = f.Address } baseURL, err := ExecuteTemplate(ctx.getBaseURL(), r) if err != nil { return PhishingTemplateContext{}, err } phishURL, _ := url.Parse(baseURL) q := phishURL.Query() q.Set(RecipientParameter, rid) phishURL.RawQuery = q.Encode() trackingURL, _ := url.Parse(baseURL) trackingURL.Path = path.Join(trackingURL.Path, "/track") trackingURL.RawQuery = q.Encode() return PhishingTemplateContext{ BaseRecipient: r, URL: phishURL.String(), TrackingURL: trackingURL.String(), Tracker: "", From: fn, RId: rid, }, nil } // ExecuteTemplate creates a templated string based on the provided // template body and data. func ExecuteTemplate(text string, data interface{}) (string, error) { buff := bytes.Buffer{} tmpl, err := template.New("template").Parse(text) if err != nil { return buff.String(), err } err = tmpl.Execute(&buff, data) return buff.String(), err }