mirror of
https://github.com/neilalexander/yggmail.git
synced 2026-05-07 20:36:28 +03:00
Lint in CI
This commit is contained in:
21
.github/workflows/ci.yml
vendored
Normal file
21
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
golangci:
|
||||||
|
name: Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- uses: actions/setup-go@v6
|
||||||
|
with:
|
||||||
|
go-version: stable
|
||||||
|
- name: golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v9
|
||||||
@@ -57,7 +57,7 @@ func main() {
|
|||||||
smtpaddr := flag.String("smtp", "localhost:1025", "SMTP listen address")
|
smtpaddr := flag.String("smtp", "localhost:1025", "SMTP listen address")
|
||||||
imapaddr := flag.String("imap", "localhost:1143", "IMAP listen address")
|
imapaddr := flag.String("imap", "localhost:1143", "IMAP listen address")
|
||||||
multicast := flag.Bool("multicast", false, "Connect to Yggdrasil peers on your LAN")
|
multicast := flag.Bool("multicast", false, "Connect to Yggdrasil peers on your LAN")
|
||||||
mcastregexp := flag.String("mcastregexp", ".*", "Regexp for multicast")
|
mcastregexp := flag.String("mcastregexp", ".*", "Regexp for multicast")
|
||||||
password := flag.Bool("password", false, "Set a new IMAP/SMTP password")
|
password := flag.Bool("password", false, "Set a new IMAP/SMTP password")
|
||||||
passwordhash := flag.String("passwordhash", "", "Set a new IMAP/SMTP password (hash)")
|
passwordhash := flag.String("passwordhash", "", "Set a new IMAP/SMTP password (hash)")
|
||||||
flag.Var(&peerAddrs, "peer", "Connect to a specific Yggdrasil static peer (this option can be given more than once)")
|
flag.Var(&peerAddrs, "peer", "Connect to a specific Yggdrasil static peer (this option can be given more than once)")
|
||||||
@@ -77,7 +77,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer storage.Close()
|
defer storage.Close() // nolint:errcheck
|
||||||
log.Printf("Using database file %q\n", *database)
|
log.Printf("Using database file %q\n", *database)
|
||||||
|
|
||||||
skStr, err := storage.ConfigGet("private_key")
|
skStr, err := storage.ConfigGet("private_key")
|
||||||
@@ -128,7 +128,7 @@ func main() {
|
|||||||
log.Println("The supplied passwords do not match")
|
log.Println("The supplied passwords do not match")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim away whitespace of UTF-8 bytes now as string
|
// trim away whitespace of UTF-8 bytes now as string
|
||||||
finalPassword := strings.TrimSpace(string(password1))
|
finalPassword := strings.TrimSpace(string(password1))
|
||||||
|
|
||||||
@@ -146,19 +146,19 @@ func main() {
|
|||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|
||||||
case passwordhash != nil && *passwordhash != "":
|
case passwordhash != nil && *passwordhash != "":
|
||||||
var hash string = strings.TrimSpace(*passwordhash);
|
var hash = strings.TrimSpace(*passwordhash)
|
||||||
if len(hash) == 0 {
|
if len(hash) == 0 {
|
||||||
log.Println("Password hash cannot be blank");
|
log.Println("Password hash cannot be blank")
|
||||||
os.Exit(1);
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Using password hash: '%v'\n", hash);
|
log.Printf("Using password hash: '%v'\n", hash)
|
||||||
|
|
||||||
if _, err := bcrypt.Cost(([]byte)(hash)); err != nil {
|
if _, err := bcrypt.Cost(([]byte)(hash)); err != nil {
|
||||||
log.Printf("The provided hash is invalid %v\n", err);
|
log.Printf("The provided hash is invalid %v\n", err)
|
||||||
os.Exit(1);
|
os.Exit(1)
|
||||||
} else if err := storage.ConfigSetPassword(hash); err != nil {
|
} else if err := storage.ConfigSetPassword(hash); err != nil {
|
||||||
log.Println("Failed to set password: ", err);
|
log.Println("Failed to set password: ", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func (b *Backend) Login(conn *imap.ConnInfo, username, password string) (backend
|
|||||||
// If our username is email-like, then take just the localpart
|
// If our username is email-like, then take just the localpart
|
||||||
if pk, err := utils.ParseAddress(username); err == nil {
|
if pk, err := utils.ParseAddress(username); err == nil {
|
||||||
if !pk.Equal(b.Config.PublicKey) {
|
if !pk.Equal(b.Config.PublicKey) {
|
||||||
b.Log.Println("Failed to authenticate IMAP user due to wrong domain", pk, b.Config.PublicKey)
|
b.Log.Println("Failed to authenticate IMAP user due to wrong domain", hex.EncodeToString(pk), hex.EncodeToString(b.Config.PublicKey))
|
||||||
return nil, fmt.Errorf("failed to authenticate: wrong domain in username")
|
return nil, fmt.Errorf("failed to authenticate: wrong domain in username")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -327,7 +327,9 @@ func (mbox *Mailbox) MoveMessages(uid bool, seqset *imap.SeqSet, dest string) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if mbox.name == "Outbox" {
|
if mbox.name == "Outbox" {
|
||||||
mbox.backend.Storage.QueueDeleteDestinationForID("Outbox", int(id))
|
if err := mbox.backend.Storage.QueueDeleteDestinationForID("Outbox", int(id)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -120,7 +120,9 @@ func (q *Queue) run() {
|
|||||||
_, mail, err := q.queues.Storage.MailSelect("Outbox", ref.ID)
|
_, mail, err := q.queues.Storage.MailSelect("Outbox", ref.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
q.queues.Storage.QueueDeleteDestinationForID("Outbox", ref.ID)
|
if err = q.queues.Storage.QueueDeleteDestinationForID("Outbox", ref.ID); err != nil {
|
||||||
|
q.queues.Log.Println("Failed delete queue destination for ID", ref.ID, "due to error:", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
q.queues.Log.Println("Failed to get mail", ref.ID, "due to error:", err)
|
q.queues.Log.Println("Failed to get mail", ref.ID, "due to error:", err)
|
||||||
}
|
}
|
||||||
@@ -134,13 +136,13 @@ func (q *Queue) run() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("q.queues.Transport.Dial: %w", err)
|
return fmt.Errorf("q.queues.Transport.Dial: %w", err)
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close() // nolint:errcheck
|
||||||
|
|
||||||
client, err := smtp.NewClient(conn, q.destination)
|
client, err := smtp.NewClient(conn, q.destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("smtp.NewClient: %w", err)
|
return fmt.Errorf("smtp.NewClient: %w", err)
|
||||||
}
|
}
|
||||||
defer client.Close()
|
defer client.Close() // nolint:errcheck
|
||||||
|
|
||||||
if err := client.Hello(hex.EncodeToString(q.queues.Config.PublicKey)); err != nil {
|
if err := client.Hello(hex.EncodeToString(q.queues.Config.PublicKey)); err != nil {
|
||||||
q.queues.Log.Println("Remote server", q.destination, "did not accept HELLO:", err)
|
q.queues.Log.Println("Remote server", q.destination, "did not accept HELLO:", err)
|
||||||
@@ -161,7 +163,7 @@ func (q *Queue) run() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("client.Data: %w", err)
|
return fmt.Errorf("client.Data: %w", err)
|
||||||
}
|
}
|
||||||
defer writer.Close()
|
defer writer.Close() // nolint:errcheck
|
||||||
|
|
||||||
if _, err := writer.Write(mail.Mail); err != nil {
|
if _, err := writer.Write(mail.Mail); err != nil {
|
||||||
return fmt.Errorf("writer.Write: %w", err)
|
return fmt.Errorf("writer.Write: %w", err)
|
||||||
|
|||||||
@@ -62,16 +62,16 @@ func (b *Backend) Login(state *smtp.ConnectionState, username, password string)
|
|||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
case BackendModeExternal:
|
case BackendModeExternal:
|
||||||
return nil, fmt.Errorf("Not expecting authenticated connection on external backend")
|
return nil, fmt.Errorf("not expecting authenticated connection on external backend")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Authenticated login failed")
|
return nil, fmt.Errorf("authenticated login failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, error) {
|
func (b *Backend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, error) {
|
||||||
switch b.Mode {
|
switch b.Mode {
|
||||||
case BackendModeInternal:
|
case BackendModeInternal:
|
||||||
return nil, fmt.Errorf("Not expecting anonymous connection on internal backend")
|
return nil, fmt.Errorf("not expecting anonymous connection on internal backend")
|
||||||
|
|
||||||
case BackendModeExternal:
|
case BackendModeExternal:
|
||||||
// The connection came from our overlay listener, so we should check
|
// The connection came from our overlay listener, so we should check
|
||||||
@@ -82,7 +82,7 @@ func (b *Backend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, err
|
|||||||
}
|
}
|
||||||
remote := hex.EncodeToString(pks)
|
remote := hex.EncodeToString(pks)
|
||||||
if state.Hostname != remote {
|
if state.Hostname != remote {
|
||||||
return nil, fmt.Errorf("You are not who you claim to be")
|
return nil, fmt.Errorf("you are not who you claim to be")
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Log.Println("Incoming SMTP session from", remote)
|
b.Log.Println("Incoming SMTP session from", remote)
|
||||||
@@ -93,5 +93,5 @@ func (b *Backend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, err
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Anonymous login failed")
|
return nil, fmt.Errorf("anonymous login failed")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func (w *Writer) Do(db *sql.DB, txn *sql.Tx, f func(txn *sql.Tx) error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Writer) run() {
|
func (w *Writer) run() {
|
||||||
if !w.running.CAS(false, true) {
|
if !w.running.CompareAndSwap(false, true) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer w.running.Store(false)
|
defer w.running.Store(false)
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ func (t *TableMailboxes) MailboxList(onlySubscribed bool) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("t.listMailboxes.Query: %w", err)
|
return nil, fmt.Errorf("t.listMailboxes.Query: %w", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close() // nolint:errcheck
|
||||||
var mailboxes []string
|
var mailboxes []string
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var mailbox string
|
var mailbox string
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ func (t *TableMails) MailSearch(mailbox string) ([]uint32, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("t.searchMail.Query: %w", err)
|
return nil, fmt.Errorf("t.searchMail.Query: %w", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close() // nolint:errcheck
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var id uint32
|
var id uint32
|
||||||
if err := rows.Scan(&id); err != nil {
|
if err := rows.Scan(&id); err != nil {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ func (t *TableQueue) QueueListDestinations() ([]string, error) {
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("t.queueSelectDestinations.Query: %w", err)
|
return nil, fmt.Errorf("t.queueSelectDestinations.Query: %w", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close() // nolint:errcheck
|
||||||
var destinations []string
|
var destinations []string
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var destination string
|
var destination string
|
||||||
@@ -118,7 +118,7 @@ func (t *TableQueue) QueueMailIDsForDestination(destination string) ([]types.Que
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("t.queueSelectDestinations.Query: %w", err)
|
return nil, fmt.Errorf("t.queueSelectDestinations.Query: %w", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close() // nolint:errcheck
|
||||||
var ids []types.QueuedMail
|
var ids []types.QueuedMail
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var id int
|
var id int
|
||||||
|
|||||||
Reference in New Issue
Block a user