From ec8b17238ee725e84f0d2cff4c20c2b8bbb362f5 Mon Sep 17 00:00:00 2001 From: Jordan Wright Date: Mon, 25 May 2020 21:46:36 -0500 Subject: [PATCH] General code cleanup as part of an effort to integrate staticcheck into our CI pipeline. --- config/config_test.go | 2 +- context/context.go | 4 +--- controllers/api/api_test.go | 12 ------------ controllers/api/group.go | 5 +++++ controllers/api/import.go | 3 --- controllers/api/util.go | 1 - controllers/api/webhook.go | 15 ++++++++++----- controllers/route.go | 6 +++--- imap/imap.go | 1 - imap/monitor.go | 4 ++-- mailer/mockmailer.go | 9 --------- middleware/middleware.go | 1 - models/campaign.go | 2 +- models/email_request.go | 4 ---- models/group.go | 1 - models/imap.go | 2 +- models/maillog.go | 2 +- models/page.go | 3 +++ models/user_test.go | 9 ++++++--- static/js/dist/app/webhooks.min.js | 2 +- static/js/src/app/webhooks.js | 12 ++++++------ util/util.go | 13 ++++++++----- webhook/webhook.go | 8 ++++++++ worker/worker.go | 8 -------- worker/worker_test.go | 4 +--- 25 files changed, 58 insertions(+), 75 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index 7e164fcd..00f8f402 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -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) } diff --git a/context/context.go b/context/context.go index 998f4939..b882406a 100644 --- a/context/context.go +++ b/context/context.go @@ -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) {} diff --git a/controllers/api/api_test.go b/controllers/api/api_test.go index b5dac5fb..35878064 100644 --- a/controllers/api/api_test.go +++ b/controllers/api/api_test.go @@ -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"} diff --git a/controllers/api/group.go b/controllers/api/group.go index 26dcfb39..700fa3e6 100644 --- a/controllers/api/group.go +++ b/controllers/api/group.go @@ -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 diff --git a/controllers/api/import.go b/controllers/api/import.go index f1b164d9..7cf96a01 100644 --- a/controllers/api/import.go +++ b/controllers/api/import.go @@ -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 } diff --git a/controllers/api/util.go b/controllers/api/util.go index 0f6c215c..9ccdc7ed 100644 --- a/controllers/api/util.go +++ b/controllers/api/util.go @@ -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 } diff --git a/controllers/api/webhook.go b/controllers/api/webhook.go index 100a235f..359142fc 100644 --- a/controllers/api/webhook.go +++ b/controllers/api/webhook.go @@ -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) } } diff --git a/controllers/route.go b/controllers/route.go index fae4ddc7..03bc8e39 100644 --- a/controllers/route.go +++ b/controllers/route.go @@ -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 { diff --git a/imap/imap.go b/imap/imap.go index f895aac8..ac2798a4 100644 --- a/imap/imap.go +++ b/imap/imap.go @@ -305,7 +305,6 @@ func getEmails(client Client, cmd *imap.Command, markAsRead, delete bool, respon } } } - return } func deleteEmail(client Client, UID uint32) error { diff --git a/imap/monitor.go b/imap/monitor.go index 4c0a61a9..34b62e79 100644 --- a/imap/monitor.go +++ b/imap/monitor.go @@ -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 { diff --git a/mailer/mockmailer.go b/mailer/mockmailer.go index 7226e94f..c39cb305 100644 --- a/mailer/mockmailer.go +++ b/mailer/mockmailer.go @@ -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() } diff --git a/middleware/middleware.go b/middleware/middleware.go index 628763cc..3b7663e9 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -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 } } diff --git a/models/campaign.go b/models/campaign.go index 9e8b4770..a9e24382 100644 --- a/models/campaign.go +++ b/models/campaign.go @@ -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"` diff --git a/models/email_request.go b/models/email_request.go index e4744c93..706fe1dd 100644 --- a/models/email_request.go +++ b/models/email_request.go @@ -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) diff --git a/models/group.go b/models/group.go index 9a5ef39e..5a4c59fd 100644 --- a/models/group.go +++ b/models/group.go @@ -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{ diff --git a/models/imap.go b/models/imap.go index 8218d5ea..e00ceaa4 100644 --- a/models/imap.go +++ b/models/imap.go @@ -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 { diff --git a/models/maillog.go b/models/maillog.go index 082ddceb..ea56ca13 100644 --- a/models/maillog.go +++ b/models/maillog.go @@ -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 diff --git a/models/page.go b/models/page.go index 30da2179..ac386ad9 100644 --- a/models/page.go +++ b/models/page.go @@ -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) diff --git a/models/user_test.go b/models/user_test.go index c869d82e..7c0819a7 100644 --- a/models/user_test.go +++ b/models/user_test.go @@ -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") } diff --git a/static/js/dist/app/webhooks.min.js b/static/js/dist/app/webhooks.min.js index 612d3b1f..765cd3e8 100644 --- a/static/js/dist/app/webhooks.min.js +++ b/static/js/dist/app/webhooks.min.js @@ -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
\n \n \n \n
\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,'"'))})})})}]); \ No newline at end of file +!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
\n \n \n \n
\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,'"'))})})})}]); \ No newline at end of file diff --git a/static/js/src/app/webhooks.js b/static/js/src/app/webhooks.js index ed7a5da4..f9c41337 100644 --- a/static/js/src/app/webhooks.js +++ b/static/js/src/app/webhooks.js @@ -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}"`) }); }; diff --git a/util/util.go b/util/util.go index 32e5a98b..bb112e62 100644 --- a/util/util.go +++ b/util/util.go @@ -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}) diff --git a/webhook/webhook.go b/webhook/webhook.go index 78773a87..b42bd618 100644 --- a/webhook/webhook.go +++ b/webhook/webhook.go @@ -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) diff --git a/worker/worker.go b/worker/worker.go index 76603edf..12b88e65 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -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) - } -} diff --git a/worker/worker_test.go b/worker/worker_test.go index 44c6eea1..87407941 100644 --- a/worker/worker_test.go +++ b/worker/worker_test.go @@ -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