Modernize Go code
authorJan Dittberner <jandd@cacert.org>
Wed, 31 Jul 2019 12:14:21 +0000 (14:14 +0200)
committerJan Dittberner <jandd@cacert.org>
Wed, 31 Jul 2019 12:14:21 +0000 (14:14 +0200)
- switch from go-logging to logrus
- handle all errors
- use gomail's NewDialer instead of deprecated NewPlainDialer

boardvoting.go
go.mod
go.sum
jobs.go
models.go
notifications.go

index e8a83e4..7c957d7 100644 (file)
@@ -23,7 +23,7 @@ import (
        "github.com/gorilla/csrf"
        "github.com/gorilla/sessions"
        _ "github.com/mattn/go-sqlite3"
-       "github.com/op/go-logging"
+       log "github.com/sirupsen/logrus"
        "gopkg.in/yaml.v2"
 
        "git.cacert.org/cacert-boardvoting/boardvoting"
@@ -35,7 +35,6 @@ var store *sessions.CookieStore
 var csrfKey []byte
 var version = "undefined"
 var build = "undefined"
-var log *logging.Logger
 
 const sessionCookieName = "votesession"
 
@@ -74,7 +73,7 @@ func renderTemplate(w http.ResponseWriter, r *http.Request, templates []string,
 type contextKey int
 
 const (
-       ctxNeedsAuth         contextKey = iota
+       ctxNeedsAuth contextKey = iota
        ctxVoter
        ctxDecision
        ctxVote
@@ -128,7 +127,7 @@ type motionParameters struct {
 }
 
 type motionListParameters struct {
-       Page int64
+       Page  int64
        Flags struct {
                Confirmed, Withdraw, Unvoted bool
        }
@@ -178,7 +177,11 @@ func motionListHandler(w http.ResponseWriter, r *http.Request) {
        if flashes := session.Flashes(); len(flashes) > 0 {
                templateContext.Flashes = flashes
        }
-       session.Save(r, w)
+       err = session.Save(r, w)
+       if err != nil {
+               http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+               return
+       }
        templateContext.Params = &params
 
        if templateContext.Decisions, err = FindDecisionsForDisplayOnPage(params.Page, params.Flags.Unvoted, templateContext.Voter); err != nil {
@@ -281,16 +284,15 @@ type FlashMessageAction struct{}
 func (a *FlashMessageAction) AddFlash(w http.ResponseWriter, r *http.Request, message interface{}, tags ...string) {
        session, err := store.Get(r, sessionCookieName)
        if err != nil {
-               log.Errorf("getting session failed: %v", err)
+               log.Warnf("could not get session cookie: %v", err)
                return
        }
        session.AddFlash(message, tags...)
-       session.Save(r, w)
+       err = session.Save(r, w)
        if err != nil {
-               log.Errorf("saving session failed: %v", err)
+               log.Warnf("could not save flash message: %v", err)
                return
        }
-       return
 }
 
 type withDrawMotionAction struct {
@@ -530,7 +532,7 @@ func (h *directVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
        case http.MethodPost:
                voteResult := &Vote{
                        VoterId: voter.Id, Vote: vote, DecisionId: decision.Id, Voted: time.Now().UTC(),
-                       Notes:   fmt.Sprintf("Direct Vote\n\n%s", getPEMClientCert(r))}
+                       Notes: fmt.Sprintf("Direct Vote\n\n%s", getPEMClientCert(r))}
                if err := voteResult.Save(); err != nil {
                        log.Errorf("Problem saving vote: %v", err)
                        http.Error(w, "Problem saving vote", http.StatusInternalServerError)
@@ -566,7 +568,10 @@ type proxyVoteHandler struct {
 func getPEMClientCert(r *http.Request) string {
        clientCertPEM := bytes.NewBufferString("")
        authenticatedCertificate := r.Context().Value(ctxAuthenticatedCert).(*x509.Certificate)
-       pem.Encode(clientCertPEM, &pem.Block{Type: "CERTIFICATE", Bytes: authenticatedCertificate.Raw})
+       err := pem.Encode(clientCertPEM, &pem.Block{Type: "CERTIFICATE", Bytes: authenticatedCertificate.Raw})
+       if err != nil {
+               log.Errorf("error encoding client certificate: %v", err)
+       }
        return clientCertPEM.String()
 }
 
@@ -692,42 +697,12 @@ type Config struct {
        MigrationsPath            string `yaml:"migrations_path"`
        HttpAddress               string `yaml:"http_address"`
        HttpsAddress              string `yaml:"https_address"`
-       MailServer struct {
+       MailServer                struct {
                Host string `yaml:"host"`
                Port int    `yaml:"port"`
        } `yaml:"mail_server"`
 }
 
-func setupLogging(ctx context.Context) {
-       log = logging.MustGetLogger("boardvoting")
-       consoleLogFormat := logging.MustStringFormatter(`%{color}%{time:20060102 15:04:05.000-0700} %{longfile} ▶ %{level:s} %{id:05d}%{color:reset} %{message}`)
-       fileLogFormat := logging.MustStringFormatter(`%{time:20060102 15:04:05.000-0700} %{level:s} %{id:05d} %{message}`)
-
-       consoleBackend := logging.NewLogBackend(os.Stderr, "", 0)
-
-       logfile, err := os.OpenFile("boardvoting.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.FileMode(0640))
-       if err != nil {
-               panic("Could not open logfile")
-       }
-
-       fileBackend := logging.NewLogBackend(logfile, "", 0)
-       fileBackendLeveled := logging.AddModuleLevel(logging.NewBackendFormatter(fileBackend, fileLogFormat))
-       fileBackendLeveled.SetLevel(logging.INFO, "")
-
-       logging.SetBackend(fileBackendLeveled,
-               logging.NewBackendFormatter(consoleBackend, consoleLogFormat))
-
-       go func() {
-               for range ctx.Done() {
-                       if err = logfile.Close(); err != nil {
-                               fmt.Fprintf(os.Stderr, "Problem closing the log file: %v", err)
-                       }
-               }
-       }()
-
-       log.Info("Setup logging")
-}
-
 func readConfig() {
        source, err := ioutil.ReadFile(configFile)
        if err != nil {
@@ -773,7 +748,7 @@ func setupDbConfig(ctx context.Context) {
        go func() {
                for range ctx.Done() {
                        if err := db.Close(); err != nil {
-                               fmt.Fprintf(os.Stderr, "Problem closing the database: %v", err)
+                               _, _ = fmt.Fprintf(os.Stderr, "Problem closing the database: %v", err)
                        }
                }
        }()
@@ -838,11 +813,12 @@ func init() {
 }
 
 func main() {
+       log.Infof("CAcert Board Voting version %s, build %s", version, build)
+
        flag.Parse()
 
        var stopAll func()
        executionContext, stopAll := context.WithCancel(context.Background())
-       setupLogging(executionContext)
        readConfig()
        setupDbConfig(executionContext)
        setupNotifications(executionContext)
@@ -852,8 +828,6 @@ func main() {
 
        defer stopAll()
 
-       log.Infof("CAcert Board Voting version %s, build %s", version, build)
-
        server := &http.Server{
                Addr:      config.HttpsAddress,
                TLSConfig: tlsConfig,
diff --git a/go.mod b/go.mod
index 1ebf8e7..b637072 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -12,8 +12,8 @@ require (
        github.com/imdario/mergo v0.3.7 // indirect
        github.com/jmoiron/sqlx v1.2.0
        github.com/mattn/go-sqlite3 v1.11.0
-       github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
        github.com/rubenv/sql-migrate v0.0.0-20190717103323-87ce952f7079
+       github.com/sirupsen/logrus v1.4.2
        github.com/ziutek/mymysql v1.5.4 // indirect
        golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect
        google.golang.org/appengine v1.6.1 // indirect
diff --git a/go.sum b/go.sum
index bf2802f..caf79c2 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -45,6 +45,7 @@ github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -59,8 +60,6 @@ github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A
 github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
-github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -72,6 +71,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
 github.com/rubenv/sql-migrate v0.0.0-20190717103323-87ce952f7079 h1:xPeaaIHjF9j8jbYQ5xdvLnFp+lpmGYFG1uBPtXNBHno=
 github.com/rubenv/sql-migrate v0.0.0-20190717103323-87ce952f7079/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -104,6 +104,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c h1:+EXw7AwNOKzPFXMZ1yNjO40aWCh3PIquJB2fYlv9wcs=
 golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
diff --git a/jobs.go b/jobs.go
index 46ed7dc..0fe6086 100644 (file)
--- a/jobs.go
+++ b/jobs.go
@@ -1,6 +1,9 @@
 package main
 
-import "time"
+import (
+       log "github.com/sirupsen/logrus"
+       "time"
+)
 
 type Job interface {
        Schedule()
index 8c2f968..a2740ad 100644 (file)
--- a/models.go
+++ b/models.go
@@ -3,10 +3,12 @@ package main
 import (
        "database/sql"
        "fmt"
-       dbmig "git.cacert.org/cacert-boardvoting/db"
        "github.com/jmoiron/sqlx"
        "github.com/rubenv/sql-migrate"
        "time"
+
+       migrations "git.cacert.org/cacert-boardvoting/db"
+       log "github.com/sirupsen/logrus"
 )
 
 type sqlKey int
@@ -250,16 +252,16 @@ func NewDB(database *sql.DB) *dbHandler {
                var stmt *sqlx.Stmt
                stmt, err := handler.db.Preparex(sqlStatement)
                if err != nil {
-                       log.Critical("ERROR parsing statement %s: %s", sqlStatement, err)
+                       log.Errorf("error parsing statement %s: %s", sqlStatement, err)
                        failedStatements = append(failedStatements, sqlStatement)
                }
-               stmt.Close()
+               _ = stmt.Close()
        }
        if len(failedStatements) > 0 {
                log.Panicf("%d statements failed to prepare", len(failedStatements))
        }
 
-       _, err := migrate.Exec(database, "sqlite3", dbmig.Migrations(), migrate.Up)
+       _, err := migrate.Exec(database, "sqlite3", migrations.Migrations(), migrate.Up)
        if err != nil {
                log.Panicf("running database migration failed: %v", err)
        }
@@ -288,7 +290,7 @@ func (d *dbHandler) getPreparedStatement(statementKey sqlKey) *sqlx.Stmt {
 
 func (v *Vote) Save() (err error) {
        insertVoteStmt := db.getPreparedNamedStatement(sqlCreateVote)
-       defer insertVoteStmt.Close()
+       defer func() { _ = insertVoteStmt.Close() }()
 
        if _, err = insertVoteStmt.Exec(v); err != nil {
                log.Errorf("saving vote failed: %v", err)
@@ -296,7 +298,7 @@ func (v *Vote) Save() (err error) {
        }
 
        getVoteStmt := db.getPreparedStatement(sqlLoadVote)
-       defer getVoteStmt.Close()
+       defer func() { _ = getVoteStmt.Close() }()
 
        if err = getVoteStmt.Get(v, v.DecisionId, v.VoterId); err != nil {
                log.Errorf("getting inserted vote failed: %v", err)
@@ -353,13 +355,14 @@ type DecisionForDisplay struct {
 
 func FindDecisionForDisplayByTag(tag string) (decision *DecisionForDisplay, err error) {
        decisionStmt := db.getPreparedStatement(sqlLoadDecisionByTag)
-       defer decisionStmt.Close()
+       defer func() { _ = decisionStmt.Close() }()
 
        decision = &DecisionForDisplay{}
        if err = decisionStmt.Get(decision, tag); err != nil {
                if err == sql.ErrNoRows {
                        decision = nil
                        err = nil
+                       return
                } else {
                        log.Errorf("getting motion %s failed: %v", tag, err)
                        return
@@ -381,7 +384,7 @@ func FindDecisionsForDisplayOnPage(page int64, unvoted bool, voter *Voter) (deci
        } else {
                decisionsStmt = db.getPreparedStatement(sqlLoadDecisions)
        }
-       defer decisionsStmt.Close()
+       defer func() { _ = decisionsStmt.Close() }()
 
        var rows *sqlx.Rows
        if unvoted && voter != nil {
@@ -393,7 +396,7 @@ func FindDecisionsForDisplayOnPage(page int64, unvoted bool, voter *Voter) (deci
                log.Errorf("loading motions for page %d failed: %v", page, err)
                return
        }
-       defer rows.Close()
+       defer func() { _ = rows.Close() }()
 
        for rows.Next() {
                var d DecisionForDisplay
@@ -412,14 +415,14 @@ func FindDecisionsForDisplayOnPage(page int64, unvoted bool, voter *Voter) (deci
 
 func (d *Decision) VoteSums() (sums *VoteSums, err error) {
        votesStmt := db.getPreparedStatement(sqlLoadVoteCountsForDecision)
-       defer votesStmt.Close()
+       defer func() { _ = votesStmt.Close() }()
 
        voteRows, err := votesStmt.Queryx(d.Id)
        if err != nil {
                log.Errorf("fetching vote sums for motion %s failed: %v", d.Tag, err)
                return
        }
-       defer voteRows.Close()
+       defer func() { _ = voteRows.Close() }()
 
        sums = &VoteSums{}
        for voteRows.Next() {
@@ -443,7 +446,7 @@ func (d *Decision) VoteSums() (sums *VoteSums, err error) {
 
 func (d *DecisionForDisplay) LoadVotes() (err error) {
        votesStmt := db.getPreparedStatement(sqlLoadVotesForDecision)
-       defer votesStmt.Close()
+       defer func() { _ = votesStmt.Close() }()
 
        err = votesStmt.Select(&d.Votes, d.Id)
        if err != nil {
@@ -456,7 +459,7 @@ func (d *DecisionForDisplay) LoadVotes() (err error) {
 func (d *Decision) OlderExists(unvoted bool, voter *Voter) (result bool, err error) {
        if unvoted && voter != nil {
                olderStmt := db.getPreparedStatement(sqlCountOlderThanUnvotedDecision)
-               defer olderStmt.Close()
+               defer func() { _ = olderStmt.Close() }()
 
                if err = olderStmt.Get(&result, d.Proposed, voter.Id); err != nil {
                        log.Errorf("finding older motions than %s failed: %v", d.Tag, err)
@@ -464,7 +467,7 @@ func (d *Decision) OlderExists(unvoted bool, voter *Voter) (result bool, err err
                }
        } else {
                olderStmt := db.getPreparedStatement(sqlCountOlderThanDecision)
-               defer olderStmt.Close()
+               defer func() { _ = olderStmt.Close() }()
 
                if err = olderStmt.Get(&result, d.Proposed); err != nil {
                        log.Errorf("finding older motions than %s failed: %v", d.Tag, err)
@@ -477,7 +480,7 @@ func (d *Decision) OlderExists(unvoted bool, voter *Voter) (result bool, err err
 
 func (d *Decision) Create() (err error) {
        insertDecisionStmt := db.getPreparedNamedStatement(sqlCreateDecision)
-       defer insertDecisionStmt.Close()
+       defer func() { _ = insertDecisionStmt.Close() }()
 
        result, err := insertDecisionStmt.Exec(d)
        if err != nil {
@@ -493,7 +496,7 @@ func (d *Decision) Create() (err error) {
        rescheduleChannel <- JobIdCloseDecisions
 
        getDecisionStmt := db.getPreparedStatement(sqlLoadDecisionById)
-       defer getDecisionStmt.Close()
+       defer func() { _ = getDecisionStmt.Close() }()
 
        err = getDecisionStmt.Get(d, lastInsertId)
        if err != nil {
@@ -506,7 +509,7 @@ func (d *Decision) Create() (err error) {
 
 func (d *Decision) LoadWithId() (err error) {
        getDecisionStmt := db.getPreparedStatement(sqlLoadDecisionById)
-       defer getDecisionStmt.Close()
+       defer func() { _ = getDecisionStmt.Close() }()
 
        err = getDecisionStmt.Get(d, d.Id)
        if err != nil {
@@ -519,7 +522,7 @@ func (d *Decision) LoadWithId() (err error) {
 
 func (d *Decision) Update() (err error) {
        updateDecisionStmt := db.getPreparedNamedStatement(sqlUpdateDecision)
-       defer updateDecisionStmt.Close()
+       defer func() { _ = updateDecisionStmt.Close() }()
 
        result, err := updateDecisionStmt.Exec(d)
        if err != nil {
@@ -541,7 +544,7 @@ func (d *Decision) Update() (err error) {
 
 func (d *Decision) UpdateStatus() (err error) {
        updateStatusStmt := db.getPreparedNamedStatement(sqlUpdateDecisionStatus)
-       defer updateStatusStmt.Close()
+       defer func() { _ = updateStatusStmt.Close() }()
 
        result, err := updateStatusStmt.Exec(d)
        if err != nil {
@@ -567,7 +570,7 @@ func (d *Decision) String() string {
 
 func FindVoterByAddress(emailAddress string) (voter *Voter, err error) {
        findVoterStmt := db.getPreparedStatement(sqlLoadEnabledVoterByEmail)
-       defer findVoterStmt.Close()
+       defer func() { _ = findVoterStmt.Close() }()
 
        voter = &Voter{}
        if err = findVoterStmt.Get(voter, emailAddress); err != nil {
@@ -595,7 +598,7 @@ func (d *Decision) Close() error {
        d.Status, reasoning = voteSums.CalculateResult(quorum, majority)
 
        closeDecisionStmt := db.getPreparedNamedStatement(sqlUpdateDecisionStatus)
-       defer closeDecisionStmt.Close()
+       defer func() { _ = closeDecisionStmt.Close() }()
 
        result, err := closeDecisionStmt.Exec(d)
        if err != nil {
@@ -618,7 +621,7 @@ func (d *Decision) Close() error {
 
 func CloseDecisions() (err error) {
        getClosableDecisionsStmt := db.getPreparedNamedStatement(sqlSelectClosableDecisions)
-       defer getClosableDecisionsStmt.Close()
+       defer func() { _ = getClosableDecisionsStmt.Close() }()
 
        decisions := make([]*Decision, 0)
        rows, err := getClosableDecisionsStmt.Queryx(struct{ Now time.Time }{time.Now().UTC()})
@@ -626,7 +629,7 @@ func CloseDecisions() (err error) {
                log.Errorf("fetching closable decisions failed: %v", err)
                return
        }
-       defer rows.Close()
+       defer func() { _ = rows.Close() }()
        for rows.Next() {
                decision := &Decision{}
                if err = rows.StructScan(decision); err != nil {
@@ -635,10 +638,10 @@ func CloseDecisions() (err error) {
                }
                decisions = append(decisions, decision)
        }
-       rows.Close()
+       defer func() { _ = rows.Close() }()
 
        for _, decision := range decisions {
-               log.Debugf("found closable decision %s", decision.Tag)
+               log.Infof("found closable decision %s", decision.Tag)
                if err = decision.Close(); err != nil {
                        log.Errorf("closing decision %s failed: %s", decision.Tag, err)
                        return
@@ -650,7 +653,7 @@ func CloseDecisions() (err error) {
 
 func GetNextPendingDecisionDue() (due *time.Time, err error) {
        getNextPendingDecisionDueStmt := db.getPreparedStatement(sqlGetNextPendingDecisionDue)
-       defer getNextPendingDecisionDueStmt.Close()
+       defer func() { _ = getNextPendingDecisionDueStmt.Close() }()
 
        row := getNextPendingDecisionDueStmt.QueryRow()
 
@@ -669,7 +672,7 @@ func GetNextPendingDecisionDue() (due *time.Time, err error) {
 
 func GetReminderVoters() (voters *[]Voter, err error) {
        getReminderVotersStmt := db.getPreparedStatement(sqlGetReminderVoters)
-       defer getReminderVotersStmt.Close()
+       defer func() { _ = getReminderVotersStmt.Close() }()
 
        voterSlice := make([]Voter, 0)
 
@@ -684,7 +687,7 @@ func GetReminderVoters() (voters *[]Voter, err error) {
 
 func FindUnvotedDecisionsForVoter(voter *Voter) (decisions *[]Decision, err error) {
        findUnvotedDecisionsForVoterStmt := db.getPreparedStatement(sqlFindUnvotedDecisionsForVoter)
-       defer findUnvotedDecisionsForVoterStmt.Close()
+       defer func() { _ = findUnvotedDecisionsForVoterStmt.Close() }()
 
        decisionsSlice := make([]Decision, 0)
 
@@ -699,7 +702,7 @@ func FindUnvotedDecisionsForVoter(voter *Voter) (decisions *[]Decision, err erro
 
 func GetVoterById(id int64) (voter *Voter, err error) {
        getVoterByIdStmt := db.getPreparedStatement(sqlGetEnabledVoterById)
-       defer getVoterByIdStmt.Close()
+       defer func() { _ = getVoterByIdStmt.Close() }()
 
        voter = &Voter{}
        if err = getVoterByIdStmt.Get(voter, id); err != nil {
@@ -712,7 +715,7 @@ func GetVoterById(id int64) (voter *Voter, err error) {
 
 func GetVotersForProxy(proxy *Voter) (voters *[]Voter, err error) {
        getVotersForProxyStmt := db.getPreparedStatement(sqlGetVotersForProxy)
-       defer getVotersForProxyStmt.Close()
+       defer func() { _ = getVotersForProxyStmt.Close() }()
 
        votersSlice := make([]Voter, 0)
 
index 25234ff..28c6a21 100644 (file)
@@ -7,6 +7,8 @@ import (
        "github.com/Masterminds/sprig"
        "gopkg.in/gomail.v2"
        "text/template"
+
+       log "github.com/sirupsen/logrus"
 )
 
 type headerData struct {
@@ -57,7 +59,7 @@ func MailNotifier(quitMailNotifier chan int) {
                        }
                        m.SetBody("text/plain", mailText.String())
 
-                       d := gomail.NewPlainDialer(config.MailServer.Host, config.MailServer.Port, "", "")
+                       d := gomail.NewDialer(config.MailServer.Host, config.MailServer.Port, "", "")
                        if err := d.DialAndSend(m); err != nil {
                                log.Errorf("sending mail failed: %v", err)
                        }