github.com/olivierlemoal/gophish@v0.9.0/controllers/phish_test.go (about)

     1  package controllers
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"log"
     9  	"net/http"
    10  	"net/url"
    11  
    12  	"github.com/gophish/gophish/config"
    13  	"github.com/gophish/gophish/models"
    14  )
    15  
    16  func (s *ControllersSuite) getFirstCampaign() models.Campaign {
    17  	campaigns, err := models.GetCampaigns(1)
    18  	s.Nil(err)
    19  	return campaigns[0]
    20  }
    21  
    22  func (s *ControllersSuite) getFirstEmailRequest() models.EmailRequest {
    23  	campaign := s.getFirstCampaign()
    24  	req := models.EmailRequest{
    25  		TemplateId:    campaign.TemplateId,
    26  		Template:      campaign.Template,
    27  		PageId:        campaign.PageId,
    28  		Page:          campaign.Page,
    29  		URL:           "http://localhost.localdomain",
    30  		UserId:        1,
    31  		BaseRecipient: campaign.Results[0].BaseRecipient,
    32  		SMTP:          campaign.SMTP,
    33  		FromAddress:   campaign.SMTP.FromAddress,
    34  	}
    35  	err := models.PostEmailRequest(&req)
    36  	s.Nil(err)
    37  	return req
    38  }
    39  
    40  func (s *ControllersSuite) openEmail(rid string) {
    41  	resp, err := http.Get(fmt.Sprintf("%s/track?%s=%s", s.phishServer.URL, models.RecipientParameter, rid))
    42  	s.Nil(err)
    43  	defer resp.Body.Close()
    44  	body, err := ioutil.ReadAll(resp.Body)
    45  	s.Nil(err)
    46  	expected, err := ioutil.ReadFile("static/images/pixel.png")
    47  	s.Nil(err)
    48  	s.Equal(bytes.Compare(body, expected), 0)
    49  }
    50  
    51  func (s *ControllersSuite) reportedEmail(rid string) {
    52  	resp, err := http.Get(fmt.Sprintf("%s/report?%s=%s", s.phishServer.URL, models.RecipientParameter, rid))
    53  	s.Nil(err)
    54  	s.Equal(resp.StatusCode, http.StatusNoContent)
    55  }
    56  
    57  func (s *ControllersSuite) reportEmail404(rid string) {
    58  	resp, err := http.Get(fmt.Sprintf("%s/report?%s=%s", s.phishServer.URL, models.RecipientParameter, rid))
    59  	s.Nil(err)
    60  	s.Equal(resp.StatusCode, http.StatusNotFound)
    61  }
    62  
    63  func (s *ControllersSuite) openEmail404(rid string) {
    64  	resp, err := http.Get(fmt.Sprintf("%s/track?%s=%s", s.phishServer.URL, models.RecipientParameter, rid))
    65  	s.Nil(err)
    66  	defer resp.Body.Close()
    67  	s.Nil(err)
    68  	s.Equal(resp.StatusCode, http.StatusNotFound)
    69  }
    70  
    71  func (s *ControllersSuite) clickLink(rid string, expectedHTML string) {
    72  	resp, err := http.Get(fmt.Sprintf("%s/?%s=%s", s.phishServer.URL, models.RecipientParameter, rid))
    73  	s.Nil(err)
    74  	defer resp.Body.Close()
    75  	body, err := ioutil.ReadAll(resp.Body)
    76  	s.Nil(err)
    77  	log.Printf("%s\n\n\n", body)
    78  	s.Equal(bytes.Compare(body, []byte(expectedHTML)), 0)
    79  }
    80  
    81  func (s *ControllersSuite) clickLink404(rid string) {
    82  	resp, err := http.Get(fmt.Sprintf("%s/?%s=%s", s.phishServer.URL, models.RecipientParameter, rid))
    83  	s.Nil(err)
    84  	defer resp.Body.Close()
    85  	s.Nil(err)
    86  	s.Equal(resp.StatusCode, http.StatusNotFound)
    87  }
    88  
    89  func (s *ControllersSuite) transparencyRequest(r models.Result, rid, path string) {
    90  	resp, err := http.Get(fmt.Sprintf("%s%s?%s=%s", s.phishServer.URL, path, models.RecipientParameter, rid))
    91  	s.Nil(err)
    92  	defer resp.Body.Close()
    93  	s.Equal(resp.StatusCode, http.StatusOK)
    94  	tr := &TransparencyResponse{}
    95  	err = json.NewDecoder(resp.Body).Decode(tr)
    96  	s.Nil(err)
    97  	s.Equal(tr.ContactAddress, s.config.ContactAddress)
    98  	s.Equal(tr.SendDate, r.SendDate)
    99  	s.Equal(tr.Server, config.ServerName)
   100  }
   101  
   102  func (s *ControllersSuite) TestOpenedPhishingEmail() {
   103  	campaign := s.getFirstCampaign()
   104  	result := campaign.Results[0]
   105  	s.Equal(result.Status, models.StatusSending)
   106  
   107  	s.openEmail(result.RId)
   108  
   109  	campaign = s.getFirstCampaign()
   110  	result = campaign.Results[0]
   111  	lastEvent := campaign.Events[len(campaign.Events)-1]
   112  	s.Equal(result.Status, models.EventOpened)
   113  	s.Equal(lastEvent.Message, models.EventOpened)
   114  	s.Equal(result.ModifiedDate, lastEvent.Time)
   115  }
   116  
   117  func (s *ControllersSuite) TestReportedPhishingEmail() {
   118  	campaign := s.getFirstCampaign()
   119  	result := campaign.Results[0]
   120  	s.Equal(result.Status, models.StatusSending)
   121  
   122  	s.reportedEmail(result.RId)
   123  
   124  	campaign = s.getFirstCampaign()
   125  	result = campaign.Results[0]
   126  	lastEvent := campaign.Events[len(campaign.Events)-1]
   127  	s.Equal(result.Reported, true)
   128  	s.Equal(lastEvent.Message, models.EventReported)
   129  	s.Equal(result.ModifiedDate, lastEvent.Time)
   130  }
   131  
   132  func (s *ControllersSuite) TestClickedPhishingLinkAfterOpen() {
   133  	campaign := s.getFirstCampaign()
   134  	result := campaign.Results[0]
   135  	s.Equal(result.Status, models.StatusSending)
   136  
   137  	s.openEmail(result.RId)
   138  	s.clickLink(result.RId, campaign.Page.HTML)
   139  
   140  	campaign = s.getFirstCampaign()
   141  	result = campaign.Results[0]
   142  	lastEvent := campaign.Events[len(campaign.Events)-1]
   143  	s.Equal(result.Status, models.EventClicked)
   144  	s.Equal(lastEvent.Message, models.EventClicked)
   145  	s.Equal(result.ModifiedDate, lastEvent.Time)
   146  }
   147  
   148  func (s *ControllersSuite) TestNoRecipientID() {
   149  	resp, err := http.Get(fmt.Sprintf("%s/track", s.phishServer.URL))
   150  	s.Nil(err)
   151  	s.Equal(resp.StatusCode, http.StatusNotFound)
   152  
   153  	resp, err = http.Get(s.phishServer.URL)
   154  	s.Nil(err)
   155  	s.Equal(resp.StatusCode, http.StatusNotFound)
   156  }
   157  
   158  func (s *ControllersSuite) TestInvalidRecipientID() {
   159  	rid := "XXXXXXXXXX"
   160  	s.openEmail404(rid)
   161  	s.clickLink404(rid)
   162  	s.reportEmail404(rid)
   163  }
   164  
   165  func (s *ControllersSuite) TestCompletedCampaignClick() {
   166  	campaign := s.getFirstCampaign()
   167  	result := campaign.Results[0]
   168  	s.Equal(result.Status, models.StatusSending)
   169  	s.openEmail(result.RId)
   170  
   171  	campaign = s.getFirstCampaign()
   172  	result = campaign.Results[0]
   173  	s.Equal(result.Status, models.EventOpened)
   174  
   175  	models.CompleteCampaign(campaign.Id, 1)
   176  	s.openEmail404(result.RId)
   177  	s.clickLink404(result.RId)
   178  
   179  	campaign = s.getFirstCampaign()
   180  	result = campaign.Results[0]
   181  	s.Equal(result.Status, models.EventOpened)
   182  }
   183  
   184  func (s *ControllersSuite) TestRobotsHandler() {
   185  	expected := []byte("User-agent: *\nDisallow: /\n")
   186  	resp, err := http.Get(fmt.Sprintf("%s/robots.txt", s.phishServer.URL))
   187  	s.Nil(err)
   188  	s.Equal(resp.StatusCode, http.StatusOK)
   189  	defer resp.Body.Close()
   190  	body, err := ioutil.ReadAll(resp.Body)
   191  	s.Nil(err)
   192  	s.Equal(bytes.Compare(body, expected), 0)
   193  }
   194  
   195  func (s *ControllersSuite) TestInvalidPreviewID() {
   196  	bogusRId := fmt.Sprintf("%sbogus", models.PreviewPrefix)
   197  	s.openEmail404(bogusRId)
   198  	s.clickLink404(bogusRId)
   199  	s.reportEmail404(bogusRId)
   200  }
   201  
   202  func (s *ControllersSuite) TestPreviewTrack() {
   203  	req := s.getFirstEmailRequest()
   204  	s.openEmail(req.RId)
   205  }
   206  
   207  func (s *ControllersSuite) TestPreviewClick() {
   208  	req := s.getFirstEmailRequest()
   209  	s.clickLink(req.RId, req.Page.HTML)
   210  }
   211  
   212  func (s *ControllersSuite) TestInvalidTransparencyRequest() {
   213  	bogusRId := fmt.Sprintf("bogus%s", TransparencySuffix)
   214  	s.openEmail404(bogusRId)
   215  	s.clickLink404(bogusRId)
   216  	s.reportEmail404(bogusRId)
   217  }
   218  
   219  func (s *ControllersSuite) TestTransparencyRequest() {
   220  	campaign := s.getFirstCampaign()
   221  	result := campaign.Results[0]
   222  	rid := fmt.Sprintf("%s%s", result.RId, TransparencySuffix)
   223  	s.transparencyRequest(result, rid, "/")
   224  	s.transparencyRequest(result, rid, "/track")
   225  	s.transparencyRequest(result, rid, "/report")
   226  
   227  	// And check with the URL encoded version of a +
   228  	rid = fmt.Sprintf("%s%s", result.RId, "%2b")
   229  	s.transparencyRequest(result, rid, "/")
   230  	s.transparencyRequest(result, rid, "/track")
   231  	s.transparencyRequest(result, rid, "/report")
   232  }
   233  
   234  func (s *ControllersSuite) TestRedirectTemplating() {
   235  	p := models.Page{
   236  		Name:        "Redirect Page",
   237  		HTML:        "<html>Test</html>",
   238  		UserId:      1,
   239  		RedirectURL: "http://example.com/{{.RId}}",
   240  	}
   241  	err := models.PostPage(&p)
   242  	s.Nil(err)
   243  	smtp, _ := models.GetSMTP(1, 1)
   244  	template, _ := models.GetTemplate(1, 1)
   245  	group, _ := models.GetGroup(1, 1)
   246  
   247  	campaign := models.Campaign{Name: "Redirect campaign"}
   248  	campaign.UserId = 1
   249  	campaign.Template = template
   250  	campaign.Page = p
   251  	campaign.SMTP = smtp
   252  	campaign.Groups = []models.Group{group}
   253  	err = models.PostCampaign(&campaign, campaign.UserId)
   254  	s.Nil(err)
   255  
   256  	client := http.Client{
   257  		CheckRedirect: func(req *http.Request, via []*http.Request) error {
   258  			return http.ErrUseLastResponse
   259  		},
   260  	}
   261  	result := campaign.Results[0]
   262  	resp, err := client.PostForm(fmt.Sprintf("%s/?%s=%s", s.phishServer.URL, models.RecipientParameter, result.RId), url.Values{"username": {"test"}, "password": {"test"}})
   263  	s.Nil(err)
   264  	defer resp.Body.Close()
   265  	s.Equal(http.StatusFound, resp.StatusCode)
   266  	expectedURL := fmt.Sprintf("http://example.com/%s", result.RId)
   267  	got, err := resp.Location()
   268  	s.Nil(err)
   269  	s.Equal(expectedURL, got.String())
   270  }