2017-12-09 21:42:07 +00:00
|
|
|
package worker
|
|
|
|
|
|
|
|
import (
|
2020-01-28 04:18:20 +00:00
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2017-12-09 21:42:07 +00:00
|
|
|
"github.com/gophish/gophish/config"
|
2020-01-28 04:18:20 +00:00
|
|
|
"github.com/gophish/gophish/mailer"
|
2017-12-09 21:42:07 +00:00
|
|
|
"github.com/gophish/gophish/models"
|
|
|
|
)
|
|
|
|
|
2020-01-28 04:18:20 +00:00
|
|
|
type logMailer struct {
|
|
|
|
queue chan []mailer.Mail
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *logMailer) Start(ctx context.Context) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *logMailer) Queue(ms []mailer.Mail) {
|
|
|
|
m.queue <- ms
|
|
|
|
}
|
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
// testContext is context to cover API related functions
|
|
|
|
type testContext struct {
|
2018-12-15 21:42:32 +00:00
|
|
|
config *config.Config
|
2017-12-09 21:42:07 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
func setupTest(t *testing.T) *testContext {
|
2018-12-15 21:42:32 +00:00
|
|
|
conf := &config.Config{
|
|
|
|
DBName: "sqlite3",
|
|
|
|
DBPath: ":memory:",
|
|
|
|
MigrationsPath: "../db/db_sqlite3/migrations/",
|
|
|
|
}
|
|
|
|
err := models.Setup(conf)
|
2017-12-09 21:42:07 +00:00
|
|
|
if err != nil {
|
2020-02-02 03:44:50 +00:00
|
|
|
t.Fatalf("Failed creating database: %v", err)
|
2017-12-09 21:42:07 +00:00
|
|
|
}
|
2020-02-02 03:44:50 +00:00
|
|
|
ctx := &testContext{}
|
|
|
|
ctx.config = conf
|
2020-02-16 04:43:34 +00:00
|
|
|
createTestData(t, ctx)
|
2020-02-02 03:44:50 +00:00
|
|
|
return ctx
|
2017-12-09 21:42:07 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
func createTestData(t *testing.T, ctx *testContext) {
|
|
|
|
ctx.config.TestFlag = true
|
2017-12-09 21:42:07 +00:00
|
|
|
// Add a group
|
|
|
|
group := models.Group{Name: "Test Group"}
|
2020-01-28 04:18:20 +00:00
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
group.Targets = append(group.Targets, models.Target{
|
|
|
|
BaseRecipient: models.BaseRecipient{
|
|
|
|
Email: fmt.Sprintf("test%d@example.com", i),
|
|
|
|
FirstName: "First",
|
|
|
|
LastName: "Example"}})
|
2017-12-09 21:42:07 +00:00
|
|
|
}
|
|
|
|
group.UserId = 1
|
|
|
|
models.PostGroup(&group)
|
|
|
|
|
|
|
|
// Add a template
|
2020-02-02 03:44:50 +00:00
|
|
|
template := models.Template{Name: "Test Template"}
|
|
|
|
template.Subject = "Test subject"
|
|
|
|
template.Text = "Text text"
|
|
|
|
template.HTML = "<html>Test</html>"
|
|
|
|
template.UserId = 1
|
|
|
|
models.PostTemplate(&template)
|
2017-12-09 21:42:07 +00:00
|
|
|
|
|
|
|
// Add a landing page
|
|
|
|
p := models.Page{Name: "Test Page"}
|
|
|
|
p.HTML = "<html>Test</html>"
|
|
|
|
p.UserId = 1
|
|
|
|
models.PostPage(&p)
|
|
|
|
|
|
|
|
// Add a sending profile
|
|
|
|
smtp := models.SMTP{Name: "Test Page"}
|
|
|
|
smtp.UserId = 1
|
|
|
|
smtp.Host = "example.com"
|
|
|
|
smtp.FromAddress = "test@test.com"
|
|
|
|
models.PostSMTP(&smtp)
|
2020-01-28 04:18:20 +00:00
|
|
|
}
|
2017-12-09 21:42:07 +00:00
|
|
|
|
2020-02-16 04:43:34 +00:00
|
|
|
func setupCampaign(id int) (*models.Campaign, error) {
|
2017-12-09 21:42:07 +00:00
|
|
|
// Setup and "launch" our campaign
|
|
|
|
// Set the status such that no emails are attempted
|
2020-01-28 04:18:20 +00:00
|
|
|
c := models.Campaign{Name: fmt.Sprintf("Test campaign - %d", id)}
|
2017-12-09 21:42:07 +00:00
|
|
|
c.UserId = 1
|
2020-01-28 04:18:20 +00:00
|
|
|
template, err := models.GetTemplate(1, 1)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c.Template = template
|
|
|
|
|
|
|
|
page, err := models.GetPage(1, 1)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c.Page = page
|
|
|
|
|
|
|
|
smtp, err := models.GetSMTP(1, 1)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-12-09 21:42:07 +00:00
|
|
|
c.SMTP = smtp
|
2020-01-28 04:18:20 +00:00
|
|
|
|
|
|
|
group, err := models.GetGroup(1, 1)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-12-09 21:42:07 +00:00
|
|
|
c.Groups = []models.Group{group}
|
2020-01-28 04:18:20 +00:00
|
|
|
err = models.PostCampaign(&c, c.UserId)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = c.UpdateStatus(models.CampaignEmailsSent)
|
|
|
|
return &c, err
|
|
|
|
}
|
|
|
|
|
2020-02-16 04:43:34 +00:00
|
|
|
func TestMailLogGrouping(t *testing.T) {
|
|
|
|
setupTest(t)
|
|
|
|
|
2020-01-28 04:18:20 +00:00
|
|
|
// Create the campaigns and unlock the maillogs so that they're picked up
|
|
|
|
// by the worker
|
|
|
|
for i := 0; i < 10; i++ {
|
2020-02-16 04:43:34 +00:00
|
|
|
campaign, err := setupCampaign(i)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating campaign: %v", err)
|
|
|
|
}
|
2020-01-28 04:18:20 +00:00
|
|
|
ms, err := models.GetMailLogsByCampaign(campaign.Id)
|
2020-02-16 04:43:34 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error getting maillogs for campaign: %v", err)
|
|
|
|
}
|
2020-01-28 04:18:20 +00:00
|
|
|
for _, m := range ms {
|
|
|
|
m.Unlock()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lm := &logMailer{queue: make(chan []mailer.Mail)}
|
|
|
|
worker := &DefaultWorker{}
|
|
|
|
worker.mailer = lm
|
|
|
|
|
|
|
|
// Trigger the worker, generating the maillogs and sending them to the
|
|
|
|
// mailer
|
|
|
|
worker.processCampaigns(time.Now())
|
|
|
|
|
|
|
|
// Verify that each slice of maillogs received belong to the same campaign
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
ms := <-lm.queue
|
|
|
|
maillog, ok := ms[0].(*models.MailLog)
|
|
|
|
if !ok {
|
2020-02-16 04:43:34 +00:00
|
|
|
t.Fatalf("unable to cast mail to models.MailLog")
|
2020-01-28 04:18:20 +00:00
|
|
|
}
|
|
|
|
expected := maillog.CampaignId
|
|
|
|
for _, m := range ms {
|
|
|
|
maillog, ok = m.(*models.MailLog)
|
|
|
|
if !ok {
|
2020-02-16 04:43:34 +00:00
|
|
|
t.Fatalf("unable to cast mail to models.MailLog")
|
2020-01-28 04:18:20 +00:00
|
|
|
}
|
|
|
|
got := maillog.CampaignId
|
2020-02-16 04:43:34 +00:00
|
|
|
if got != expected {
|
|
|
|
t.Fatalf("unexpected campaign ID received for maillog: got %d expected %d", got, expected)
|
|
|
|
}
|
2020-01-28 04:18:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|