gophish/controllers/phish_test.go

231 lines
6.6 KiB
Go

package controllers
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"github.com/gophish/gophish/config"
"github.com/gophish/gophish/models"
)
func (s *ControllersSuite) getFirstCampaign() models.Campaign {
campaigns, err := models.GetCampaigns(1)
s.Nil(err)
return campaigns[0]
}
func (s *ControllersSuite) getFirstEmailRequest() models.EmailRequest {
campaign := s.getFirstCampaign()
req := models.EmailRequest{
TemplateId: campaign.TemplateId,
Template: campaign.Template,
PageId: campaign.PageId,
Page: campaign.Page,
URL: "http://localhost.localdomain",
UserId: 1,
BaseRecipient: campaign.Results[0].BaseRecipient,
SMTP: campaign.SMTP,
}
err := models.PostEmailRequest(&req)
s.Nil(err)
return req
}
func (s *ControllersSuite) openEmail(rid string) {
resp, err := http.Get(fmt.Sprintf("%s/track?%s=%s", ps.URL, models.RecipientParameter, rid))
s.Nil(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
s.Nil(err)
expected, err := ioutil.ReadFile("static/images/pixel.png")
s.Nil(err)
s.Equal(bytes.Compare(body, expected), 0)
}
func (s *ControllersSuite) reportedEmail(rid string) {
resp, err := http.Get(fmt.Sprintf("%s/report?%s=%s", ps.URL, models.RecipientParameter, rid))
s.Nil(err)
s.Equal(resp.StatusCode, http.StatusNoContent)
}
func (s *ControllersSuite) reportEmail404(rid string) {
resp, err := http.Get(fmt.Sprintf("%s/report?%s=%s", ps.URL, models.RecipientParameter, rid))
s.Nil(err)
s.Equal(resp.StatusCode, http.StatusNotFound)
}
func (s *ControllersSuite) openEmail404(rid string) {
resp, err := http.Get(fmt.Sprintf("%s/track?%s=%s", ps.URL, models.RecipientParameter, rid))
s.Nil(err)
defer resp.Body.Close()
s.Nil(err)
s.Equal(resp.StatusCode, http.StatusNotFound)
}
func (s *ControllersSuite) clickLink(rid string, expectedHTML string) {
resp, err := http.Get(fmt.Sprintf("%s/?%s=%s", ps.URL, models.RecipientParameter, rid))
s.Nil(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
s.Nil(err)
log.Printf("%s\n\n\n", body)
s.Equal(bytes.Compare(body, []byte(expectedHTML)), 0)
}
func (s *ControllersSuite) clickLink404(rid string) {
resp, err := http.Get(fmt.Sprintf("%s/?%s=%s", ps.URL, models.RecipientParameter, rid))
s.Nil(err)
defer resp.Body.Close()
s.Nil(err)
s.Equal(resp.StatusCode, http.StatusNotFound)
}
func (s *ControllersSuite) transparencyRequest(r models.Result, rid, path string) {
resp, err := http.Get(fmt.Sprintf("%s%s?%s=%s", ps.URL, path, models.RecipientParameter, rid))
s.Nil(err)
defer resp.Body.Close()
s.Equal(resp.StatusCode, http.StatusOK)
tr := &TransparencyResponse{}
err = json.NewDecoder(resp.Body).Decode(tr)
s.Nil(err)
s.Equal(tr.ContactAddress, config.Conf.ContactAddress)
s.Equal(tr.SendDate, r.SendDate)
s.Equal(tr.Server, ServerName)
}
func (s *ControllersSuite) TestOpenedPhishingEmail() {
campaign := s.getFirstCampaign()
result := campaign.Results[0]
s.Equal(result.Status, models.STATUS_SENDING)
s.openEmail(result.RId)
campaign = s.getFirstCampaign()
result = campaign.Results[0]
lastEvent := campaign.Events[len(campaign.Events)-1]
s.Equal(result.Status, models.EVENT_OPENED)
s.Equal(lastEvent.Message, models.EVENT_OPENED)
s.Equal(result.ModifiedDate, lastEvent.Time)
}
func (s *ControllersSuite) TestReportedPhishingEmail() {
campaign := s.getFirstCampaign()
result := campaign.Results[0]
s.Equal(result.Status, models.STATUS_SENDING)
s.reportedEmail(result.RId)
campaign = s.getFirstCampaign()
result = campaign.Results[0]
lastEvent := campaign.Events[len(campaign.Events)-1]
s.Equal(result.Reported, true)
s.Equal(lastEvent.Message, models.EVENT_REPORTED)
s.Equal(result.ModifiedDate, lastEvent.Time)
}
func (s *ControllersSuite) TestClickedPhishingLinkAfterOpen() {
campaign := s.getFirstCampaign()
result := campaign.Results[0]
s.Equal(result.Status, models.STATUS_SENDING)
s.openEmail(result.RId)
s.clickLink(result.RId, campaign.Page.HTML)
campaign = s.getFirstCampaign()
result = campaign.Results[0]
lastEvent := campaign.Events[len(campaign.Events)-1]
s.Equal(result.Status, models.EVENT_CLICKED)
s.Equal(lastEvent.Message, models.EVENT_CLICKED)
s.Equal(result.ModifiedDate, lastEvent.Time)
}
func (s *ControllersSuite) TestNoRecipientID() {
resp, err := http.Get(fmt.Sprintf("%s/track", ps.URL))
s.Nil(err)
s.Equal(resp.StatusCode, http.StatusNotFound)
resp, err = http.Get(ps.URL)
s.Nil(err)
s.Equal(resp.StatusCode, http.StatusNotFound)
}
func (s *ControllersSuite) TestInvalidRecipientID() {
rid := "XXXXXXXXXX"
s.openEmail404(rid)
s.clickLink404(rid)
s.reportEmail404(rid)
}
func (s *ControllersSuite) TestCompletedCampaignClick() {
campaign := s.getFirstCampaign()
result := campaign.Results[0]
s.Equal(result.Status, models.STATUS_SENDING)
s.openEmail(result.RId)
campaign = s.getFirstCampaign()
result = campaign.Results[0]
s.Equal(result.Status, models.EVENT_OPENED)
models.CompleteCampaign(campaign.Id, 1)
s.openEmail404(result.RId)
s.clickLink404(result.RId)
campaign = s.getFirstCampaign()
result = campaign.Results[0]
s.Equal(result.Status, models.EVENT_OPENED)
}
func (s *ControllersSuite) TestRobotsHandler() {
expected := []byte("User-agent: *\nDisallow: /\n")
resp, err := http.Get(fmt.Sprintf("%s/robots.txt", ps.URL))
s.Nil(err)
s.Equal(resp.StatusCode, http.StatusOK)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
s.Nil(err)
s.Equal(bytes.Compare(body, expected), 0)
}
func (s *ControllersSuite) TestInvalidPreviewID() {
bogusRId := fmt.Sprintf("%sbogus", models.PreviewPrefix)
s.openEmail404(bogusRId)
s.clickLink404(bogusRId)
s.reportEmail404(bogusRId)
}
func (s *ControllersSuite) TestPreviewTrack() {
req := s.getFirstEmailRequest()
s.openEmail(req.RId)
}
func (s *ControllersSuite) TestPreviewClick() {
req := s.getFirstEmailRequest()
s.clickLink(req.RId, req.Page.HTML)
}
func (s *ControllersSuite) TestInvalidTransparencyRequest() {
bogusRId := fmt.Sprintf("bogus%s", TransparencySuffix)
s.openEmail404(bogusRId)
s.clickLink404(bogusRId)
s.reportEmail404(bogusRId)
}
func (s *ControllersSuite) TestTransparencyRequest() {
campaign := s.getFirstCampaign()
result := campaign.Results[0]
rid := fmt.Sprintf("%s%s", result.RId, TransparencySuffix)
s.transparencyRequest(result, rid, "/")
s.transparencyRequest(result, rid, "/track")
s.transparencyRequest(result, rid, "/report")
// And check with the URL encoded version of a +
rid = fmt.Sprintf("%s%s", result.RId, "%2b")
s.transparencyRequest(result, rid, "/")
s.transparencyRequest(result, rid, "/track")
s.transparencyRequest(result, rid, "/report")
}