General code cleanup as part of an effort to integrate staticcheck into our CI pipeline.

This commit is contained in:
Jordan Wright 2020-05-25 21:46:36 -05:00
parent 0961e22126
commit ec8b17238e
25 changed files with 58 additions and 75 deletions

View file

@ -68,7 +68,7 @@ func TestLoadConfig(t *testing.T) {
}
// Load an invalid config
conf, err = LoadConfig("bogusfile")
_, err = LoadConfig("bogusfile")
if err == nil {
t.Fatalf("expected error when loading invalid config, but got %v", err)
}

View file

@ -23,6 +23,4 @@ func Set(r *http.Request, key, val interface{}) *http.Request {
}
// Clear is a null operation, since this is handled automatically in Go > 1.7
func Clear(r *http.Request) {
return
}
func Clear(r *http.Request) {}

View file

@ -42,18 +42,6 @@ func setupTest(t *testing.T) *testContext {
return ctx
}
func tearDown(t *testing.T, ctx *testContext) {
// Cleanup all users except the original admin
// users, _ := models.GetUsers()
// for _, user := range users {
// if user.Id == 1 {
// continue
// }
// err := models.DeleteUser(user.Id)
// s.Nil(err)
// }
}
func createTestData(t *testing.T) {
// Add a group
group := models.Group{Name: "Test Group"}

View file

@ -87,6 +87,11 @@ func (as *Server) Group(w http.ResponseWriter, r *http.Request) {
// Change this to get from URL and uid (don't bother with id in r.Body)
g = models.Group{}
err = json.NewDecoder(r.Body).Decode(&g)
if err != nil {
log.Errorf("error decoding group: %v", err)
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
return
}
if g.Id != id {
JSONResponse(w, models.Response{Success: false, Message: "Error: /:id and group_id mismatch"}, http.StatusInternalServerError)
return

View file

@ -46,7 +46,6 @@ func (as *Server) ImportGroup(w http.ResponseWriter, r *http.Request) {
return
}
JSONResponse(w, ts, http.StatusOK)
return
}
// ImportEmail allows for the importing of email.
@ -94,7 +93,6 @@ func (as *Server) ImportEmail(w http.ResponseWriter, r *http.Request) {
HTML: string(e.HTML),
}
JSONResponse(w, er, http.StatusOK)
return
}
// ImportSite allows for the importing of HTML from a website
@ -153,5 +151,4 @@ func (as *Server) ImportSite(w http.ResponseWriter, r *http.Request) {
}
cs := cloneResponse{HTML: h}
JSONResponse(w, cs, http.StatusOK)
return
}

View file

@ -118,5 +118,4 @@ func (as *Server) SendTestEmail(w http.ResponseWriter, r *http.Request) {
return
}
JSONResponse(w, models.Response{Success: true, Message: "Email Sent"}, http.StatusOK)
return
}

View file

@ -62,15 +62,20 @@ func (as *Server) Webhook(w http.ResponseWriter, r *http.Request) {
JSONResponse(w, models.Response{Success: true, Message: "Webhook deleted Successfully!"}, http.StatusOK)
case r.Method == "PUT":
wh2 := models.Webhook{}
err = json.NewDecoder(r.Body).Decode(&wh2)
wh2.Id = id
err = models.PutWebhook(&wh2)
wh = models.Webhook{}
err = json.NewDecoder(r.Body).Decode(&wh)
if err != nil {
log.Errorf("error decoding webhook: %v", err)
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
return
}
wh.Id = id
err = models.PutWebhook(&wh)
if err != nil {
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
return
}
JSONResponse(w, wh2, http.StatusOK)
JSONResponse(w, wh, http.StatusOK)
}
}

View file

@ -285,7 +285,7 @@ func (as *AdminServer) Impersonate(w http.ResponseWriter, r *http.Request) {
session.Values["id"] = u.Id
session.Save(r, w)
}
http.Redirect(w, r, "/", 302)
http.Redirect(w, r, "/", http.StatusFound)
}
// Login handles the authentication flow for a user. If credentials are valid,
@ -326,7 +326,7 @@ func (as *AdminServer) Login(w http.ResponseWriter, r *http.Request) {
next = path
}
}
http.Redirect(w, r, next, 302)
http.Redirect(w, r, next, http.StatusFound)
} else {
Flash(w, r, "danger", "Invalid Username/Password")
params.Flashes = session.Flashes()
@ -349,7 +349,7 @@ func (as *AdminServer) Logout(w http.ResponseWriter, r *http.Request) {
delete(session.Values, "id")
Flash(w, r, "success", "You have successfully logged out")
session.Save(r, w)
http.Redirect(w, r, "/login", 302)
http.Redirect(w, r, "/login", http.StatusFound)
}
func getTemplate(w http.ResponseWriter, tmpl string) *template.Template {

View file

@ -305,7 +305,6 @@ func getEmails(client Client, cmd *imap.Command, markAsRead, delete bool, respon
}
}
}
return
}
func deleteEmail(client Client, UID uint32) error {

View file

@ -162,7 +162,7 @@ func checkForNewEmails(im models.IMAP) {
if err != nil {
log.Error("Error updating GoPhish email with rid ", rid, ": ", err.Error())
} else {
if im.DeleteReportedCampaignEmail == true {
if im.DeleteReportedCampaignEmail {
campaignEmails = append(campaignEmails, m.UID)
}
}
@ -180,7 +180,7 @@ func checkForNewEmails(im models.IMAP) {
}
}
// If the DeleteReportedCampaignEmail flag is set, delete reported Gophish campaign emails
if im.DeleteReportedCampaignEmail == true && len(campaignEmails) > 0 {
if im.DeleteReportedCampaignEmail && len(campaignEmails) > 0 {
log.Debugf("Deleting %d campaign emails\n", len(campaignEmails))
err := mailServer.DeleteEmails(campaignEmails) // Delete GoPhish campaign emails.
if err != nil {

View file

@ -13,11 +13,6 @@ import (
// being unreachable
var errHostUnreachable = errors.New("host unreachable")
// errDialerUnavailable is a mock error to represent a dialer
// being unavailable (perhaps an error getting the dialer config
// or a database error)
var errDialerUnavailable = errors.New("dialer unavailable")
// mockDialer keeps track of calls to Dial
type mockDialer struct {
dialCount int
@ -137,10 +132,6 @@ func (mm *mockMessage) defaultDialer() (Dialer, error) {
return newMockDialer(), nil
}
func (mm *mockMessage) errorDialer() (Dialer, error) {
return nil, errDialerUnavailable
}
func (mm *mockMessage) GetDialer() (Dialer, error) {
return mm.getdialer()
}

View file

@ -120,7 +120,6 @@ func RequireLogin(handler http.Handler) http.HandlerFunc {
q := r.URL.Query()
q.Set("next", r.URL.Path)
http.Redirect(w, r, fmt.Sprintf("/login?%s", q.Encode()), http.StatusTemporaryRedirect)
return
}
}

View file

@ -27,7 +27,7 @@ type Campaign struct {
Status string `json:"status"`
Results []Result `json:"results,omitempty"`
Groups []Group `json:"groups,omitempty"`
Events []Event `json:"timeline,omitemtpy"`
Events []Event `json:"timeline,omitempty"`
SMTPId int64 `json:"-"`
SMTP SMTP `json:"smtp"`
URL string `json:"url"`

View file

@ -103,10 +103,6 @@ func (s *EmailRequest) Generate(msg *gomail.Message) error {
if err != nil {
return err
}
fn := f.Name
if fn == "" {
fn = f.Address
}
msg.SetAddressHeader("From", f.Address, f.Name)
ptx, err := NewPhishingTemplateContext(s, s.BaseRecipient, s.RId)

View file

@ -226,7 +226,6 @@ func PutGroup(g *Group) error {
return err
}
// Fetch group's existing targets from database.
ts := []Target{}
ts, err := GetTargets(g.Id)
if err != nil {
log.WithFields(logrus.Fields{

View file

@ -53,7 +53,7 @@ var ErrIMAPPasswordNotSpecified = errors.New("No Password specified")
// ErrInvalidIMAPFreq is thrown when the frequency for polling the
// IMAP server is invalid
var ErrInvalidIMAPFreq = errors.New("Invalid polling frequency.")
var ErrInvalidIMAPFreq = errors.New("Invalid polling frequency")
// TableName specifies the database tablename for Gorm to use
func (im IMAP) TableName() string {

View file

@ -125,7 +125,7 @@ func (m *MailLog) Success() error {
return err
}
err = db.Delete(m).Error
return nil
return err
}
// GetDialer returns a dialer based on the maillog campaign's SMTP configuration

View file

@ -138,6 +138,9 @@ func PostPage(p *Page) error {
// Per the PUT Method RFC, it presumes all data for a page is provided.
func PutPage(p *Page) error {
err := p.Validate()
if err != nil {
return err
}
err = db.Where("id=?", p.Id).Save(p).Error
if err != nil {
log.Error(err)

View file

@ -27,7 +27,9 @@ func (s *ModelsSuite) TestGetUserByAPIKeyWithExistingAPIKey(c *check.C) {
u, err := GetUser(1)
c.Assert(err, check.Equals, nil)
u, err = GetUserByAPIKey(u.ApiKey)
got, err := GetUserByAPIKey(u.ApiKey)
c.Assert(err, check.Equals, nil)
c.Assert(got.Id, check.Equals, u.Id)
}
func (s *ModelsSuite) TestGetUserByAPIKeyWithNotExistingAPIKey(c *check.C) {
@ -46,11 +48,12 @@ func (s *ModelsSuite) TestGetUserByUsernameWithNotExistingUser(c *check.C) {
}
func (s *ModelsSuite) TestPutUser(c *check.C) {
u, err := GetUser(1)
u, _ := GetUser(1)
u.Username = "admin_changed"
err = PutUser(&u)
err := PutUser(&u)
c.Assert(err, check.Equals, nil)
u, err = GetUser(1)
c.Assert(err, check.Equals, nil)
c.Assert(u.Username, check.Equals, "admin_changed")
}

View file

@ -1 +1 @@
!function(e){var o={};function n(t){if(o[t])return o[t].exports;var a=o[t]={i:t,l:!1,exports:{}};return e[t].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:t})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,o){if(1&o&&(e=n(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var a in e)n.d(t,a,function(o){return e[o]}.bind(null,a));return t},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},n.p="",n(n.s=1)}([,function(e,o){var n=[],t=function(){$("#name").val(""),$("#url").val(""),$("#secret").val(""),$("#is_active").prop("checked",!1),$("#flashes").empty()},a=function(){$("#webhookTable").hide(),$("#loading").show(),api.webhooks.get().success(function(e){n=e,$("#loading").hide(),$("#webhookTable").show();var o=$("#webhookTable").DataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]});o.clear(),$.each(n,function(e,n){o.row.add([escapeHtml(n.name),escapeHtml(n.url),escapeHtml(n.is_active),'\n <div class="pull-right">\n <button class="btn btn-primary ping_button" data-webhook-id="'.concat(n.id,'">\n Ping\n </button>\n <button class="btn btn-primary edit_button" data-toggle="modal" data-backdrop="static" data-target="#modal" data-webhook-id="').concat(n.id,'">\n <i class="fa fa-pencil"></i>\n </button>\n <button class="btn btn-danger delete_button" data-webhook-id="').concat(n.id,'">\n <i class="fa fa-trash-o"></i>\n </button>\n </div>\n ')]).draw()})}).error(function(){errorFlash("Error fetching webhooks")})},c=function(e){$("#modalSubmit").unbind("click").click(function(){!function(e){var o={name:$("#name").val(),url:$("#url").val(),secret:$("#secret").val(),is_active:$("#is_active").is(":checked")};-1!=e?(o.id=e,api.webhookId.put(o).success(function(e){t(),a(),$("#modal").modal("hide"),successFlash('Webhook "'.concat(escape(o.name),'" has been updated successfully!'))}).error(function(e){modalError(e.responseJSON.message)})):api.webhooks.post(o).success(function(e){a(),t(),$("#modal").modal("hide"),successFlash('Webhook "'.concat(escape(o.name),'" has been created successfully!'))}).error(function(e){modalError(e.responseJSON.message)})}(e)}),-1!==e&&api.webhookId.get(e).success(function(e){$("#name").val(e.name),$("#url").val(e.url),$("#secret").val(e.secret),$("#is_active").prop("checked",e.is_active)}).error(function(){errorFlash("Error fetching webhook")})};$(document).ready(function(){a(),$("#modal").on("hide.bs.modal",function(){t()}),$("#new_button").on("click",function(){c(-1)}),$("#webhookTable").on("click",".edit_button",function(e){c($(this).attr("data-webhook-id"))}),$("#webhookTable").on("click",".delete_button",function(e){var o,t;o=$(this).attr("data-webhook-id"),(t=n.find(function(e){return e.id==o}))&&Swal.fire({title:"Are you sure?",text:"This will delete the webhook '".concat(escape(t.name),"'"),type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete",confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise(function(e,n){api.webhookId.delete(o).success(function(o){e()}).error(function(e){n(e.responseJSON.message)})}).catch(function(e){Swal.showValidationMessage(e)})}}).then(function(e){e.value&&Swal.fire("Webhook Deleted!","The webhook has been deleted!","success"),$("button:contains('OK')").on("click",function(){location.reload()})})}),$("#webhookTable").on("click",".ping_button",function(e){var o,a;o=e.currentTarget,a=e.currentTarget.dataset.webhookId,t(),o.disabled=!0,api.webhookId.ping(a).success(function(e){o.disabled=!1,successFlash('Ping of "'.concat(escape(e.name),'" webhook succeeded.'))}).error(function(e){o.disabled=!1;var t=n.find(function(e){return e.id==a});t&&errorFlash('Ping of "'.concat(escape(t.name),'" webhook failed: "').concat(e.responseJSON.message,'"'))})})})}]);
!function(e){var t={};function n(o){if(t[o])return t[o].exports;var a=t[o]={i:o,l:!1,exports:{}};return e[o].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(o,a,function(t){return e[t]}.bind(null,a));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([,function(e,t){var n=[],o=function(){$("#name").val(""),$("#url").val(""),$("#secret").val(""),$("#is_active").prop("checked",!1),$("#flashes").empty()},a=function(){$("#webhookTable").hide(),$("#loading").show(),api.webhooks.get().success(function(e){n=e,$("#loading").hide(),$("#webhookTable").show();var t=$("#webhookTable").DataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]});t.clear(),$.each(n,function(e,n){t.row.add([escapeHtml(n.name),escapeHtml(n.url),escapeHtml(n.is_active),'\n <div class="pull-right">\n <button class="btn btn-primary ping_button" data-webhook-id="'.concat(n.id,'">\n Ping\n </button>\n <button class="btn btn-primary edit_button" data-toggle="modal" data-backdrop="static" data-target="#modal" data-webhook-id="').concat(n.id,'">\n <i class="fa fa-pencil"></i>\n </button>\n <button class="btn btn-danger delete_button" data-webhook-id="').concat(n.id,'">\n <i class="fa fa-trash-o"></i>\n </button>\n </div>\n ')]).draw()})}).error(function(){errorFlash("Error fetching webhooks")})},c=function(e){$("#modalSubmit").unbind("click").click(function(){!function(e){var t={name:$("#name").val(),url:$("#url").val(),secret:$("#secret").val(),is_active:$("#is_active").is(":checked")};-1!=e?(t.id=parseInt(e),api.webhookId.put(t).success(function(e){o(),a(),$("#modal").modal("hide"),successFlash('Webhook "'.concat(escapeHtml(t.name),'" has been updated successfully!'))}).error(function(e){modalError(e.responseJSON.message)})):api.webhooks.post(t).success(function(e){a(),o(),$("#modal").modal("hide"),successFlash('Webhook "'.concat(escapeHtml(t.name),'" has been created successfully!'))}).error(function(e){modalError(e.responseJSON.message)})}(e)}),-1!==e&&api.webhookId.get(e).success(function(e){$("#name").val(e.name),$("#url").val(e.url),$("#secret").val(e.secret),$("#is_active").prop("checked",e.is_active)}).error(function(){errorFlash("Error fetching webhook")})};$(document).ready(function(){a(),$("#modal").on("hide.bs.modal",function(){o()}),$("#new_button").on("click",function(){c(-1)}),$("#webhookTable").on("click",".edit_button",function(e){c($(this).attr("data-webhook-id"))}),$("#webhookTable").on("click",".delete_button",function(e){var t,o;t=$(this).attr("data-webhook-id"),(o=n.find(function(e){return e.id==t}))&&Swal.fire({title:"Are you sure?",text:"This will delete the webhook '".concat(escapeHtml(o.name),"'"),type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete",confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise(function(e,n){api.webhookId.delete(t).success(function(t){e()}).error(function(e){n(e.responseJSON.message)})}).catch(function(e){Swal.showValidationMessage(e)})}}).then(function(e){e.value&&Swal.fire("Webhook Deleted!","The webhook has been deleted!","success"),$("button:contains('OK')").on("click",function(){location.reload()})})}),$("#webhookTable").on("click",".ping_button",function(e){var t,a;t=e.currentTarget,a=e.currentTarget.dataset.webhookId,o(),t.disabled=!0,api.webhookId.ping(a).success(function(e){t.disabled=!1,successFlash('Ping of "'.concat(escapeHtml(e.name),'" webhook succeeded.'))}).error(function(e){t.disabled=!1;var o=n.find(function(e){return e.id==a});o&&errorFlash('Ping of "'.concat(escapeHtml(o.name),'" webhook failed: "').concat(e.responseJSON.message,'"'))})})})}]);

View file

@ -16,13 +16,13 @@ const saveWebhook = (id) => {
is_active: $("#is_active").is(":checked"),
};
if (id != -1) {
wh.id = id;
wh.id = parseInt(id);
api.webhookId.put(wh)
.success(function(data) {
dismiss();
load();
$("#modal").modal("hide");
successFlash(`Webhook "${escape(wh.name)}" has been updated successfully!`);
successFlash(`Webhook "${escapeHtml(wh.name)}" has been updated successfully!`);
})
.error(function(data) {
modalError(data.responseJSON.message)
@ -33,7 +33,7 @@ const saveWebhook = (id) => {
load();
dismiss();
$("#modal").modal("hide");
successFlash(`Webhook "${escape(wh.name)}" has been created successfully!`);
successFlash(`Webhook "${escapeHtml(wh.name)}" has been created successfully!`);
})
.error(function(data) {
modalError(data.responseJSON.message)
@ -108,7 +108,7 @@ const deleteWebhook = (id) => {
}
Swal.fire({
title: "Are you sure?",
text: `This will delete the webhook '${escape(wh.name)}'`,
text: `This will delete the webhook '${escapeHtml(wh.name)}'`,
type: "warning",
animation: false,
showCancelButton: true,
@ -150,7 +150,7 @@ const pingUrl = (btn, whId) => {
api.webhookId.ping(whId)
.success(function(wh) {
btn.disabled = false;
successFlash(`Ping of "${escape(wh.name)}" webhook succeeded.`);
successFlash(`Ping of "${escapeHtml(wh.name)}" webhook succeeded.`);
})
.error(function(data) {
btn.disabled = false;
@ -158,7 +158,7 @@ const pingUrl = (btn, whId) => {
if (!wh) {
return
}
errorFlash(`Ping of "${escape(wh.name)}" webhook failed: "${data.responseJSON.message}"`)
errorFlash(`Ping of "${escapeHtml(wh.name)}" webhook failed: "${data.responseJSON.message}"`)
});
};

View file

@ -138,6 +138,9 @@ func CheckAndCreateSSL(cp string, kp string) error {
log.Infof("Creating new self-signed certificates for administration interface")
priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
return fmt.Errorf("error generating tls private key: %v", err)
}
notBefore := time.Now()
// Generate a certificate that lasts for 10 years
@ -147,7 +150,7 @@ func CheckAndCreateSSL(cp string, kp string) error {
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return fmt.Errorf("TLS Certificate Generation: Failed to generate a random serial number: %s", err)
return fmt.Errorf("tls certificate generation: failed to generate a random serial number: %s", err)
}
template := x509.Certificate{
@ -165,24 +168,24 @@ func CheckAndCreateSSL(cp string, kp string) error {
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv)
if err != nil {
return fmt.Errorf("TLS Certificate Generation: Failed to create certificate: %s", err)
return fmt.Errorf("tls certificate generation: failed to create certificate: %s", err)
}
certOut, err := os.Create(cp)
if err != nil {
return fmt.Errorf("TLS Certificate Generation: Failed to open %s for writing: %s", cp, err)
return fmt.Errorf("tls certificate generation: failed to open %s for writing: %s", cp, err)
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
keyOut, err := os.OpenFile(kp, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return fmt.Errorf("TLS Certificate Generation: Failed to open %s for writing", kp)
return fmt.Errorf("tls certificate generation: failed to open %s for writing", kp)
}
b, err := x509.MarshalECPrivateKey(priv)
if err != nil {
return fmt.Errorf("TLS Certificate Generation: Unable to marshal ECDSA private key: %v", err)
return fmt.Errorf("tls certificate generation: unable to marshal ECDSA private key: %v", err)
}
pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b})

View file

@ -76,7 +76,15 @@ func (ds defaultSender) Send(endPoint EndPoint, data interface{}) error {
}
req, err := http.NewRequest("POST", endPoint.URL, bytes.NewBuffer(jsonData))
if err != nil {
log.Error(err)
return err
}
signat, err := sign(endPoint.Secret, jsonData)
if err != nil {
log.Error(err)
return err
}
req.Header.Set(SignatureHeader, fmt.Sprintf("%s=%s", Sha256Prefix, signat))
req.Header.Set("Content-Type", "application/json")
resp, err := ds.client.Do(req)

View file

@ -155,11 +155,3 @@ func (w *DefaultWorker) SendTestEmail(s *models.EmailRequest) error {
}()
return <-s.ErrorChan
}
// errorMail is a helper to handle erroring out a slice of Mail instances
// in the case that an unrecoverable error occurs.
func errorMail(err error, ms []mailer.Mail) {
for _, m := range ms {
m.Error(err)
}
}

View file

@ -15,9 +15,7 @@ type logMailer struct {
queue chan []mailer.Mail
}
func (m *logMailer) Start(ctx context.Context) {
return
}
func (m *logMailer) Start(ctx context.Context) {}
func (m *logMailer) Queue(ms []mailer.Mail) {
m.queue <- ms