internal/control/adminmail.go

v1.39.0
gitbay/internal/control/adminmail.go history · blame · raw

68 lines · 2057 bytes

 1package control
 2
 3import (
 4	"fmt"
 5	"io"
 6	"time"
 7
 8	"gitbay.org/gitbay/internal/imapc"
 9	"gitbay.org/gitbay/internal/protocol"
10)
11
12func init() {
13	register(Command{Path: []string{"admin", "mail", "inbound", "check"},
14		Summary:  "connect to the reply mailbox read-only and report what is waiting",
15		Usage:    "admin mail inbound check",
16		Examples: []string{"admin mail inbound check"},
17		ReadOnly: true, Run: runAdminMailInboundCheck})
18}
19
20const unauthenticatedWarning = "trusted_authserv_id is unset: a reply's From is not checked against the mail host's DMARC and DKIM results"
21
22// runAdminMailInboundCheck logs in to the [mail.inbound] mailbox and
23// opens it with EXAMINE, which changes no flag, so a check never marks a
24// reply seen before the poller reads it.
25func runAdminMailInboundCheck(c *Ctx, args []string) int {
26	if code := requireInstanceAdmin(c); code >= 0 {
27		return code
28	}
29	if len(args) != 0 {
30		return c.usage()
31	}
32	in := c.Cfg.Mail.Inbound
33	type out struct {
34		Enabled  bool   `json:"enabled"`
35		Server   string `json:"server,omitempty"`
36		Mailbox  string `json:"mailbox,omitempty"`
37		Messages int    `json:"messages"`
38		Unseen   int    `json:"unseen"`
39		Warning  string `json:"warning,omitempty"`
40	}
41	if !in.Enabled {
42		return c.emit(out{}, func(w io.Writer) {
43			fmt.Fprintln(w, "inbound mail is off ([mail.inbound] enabled = false)")
44		})
45	}
46	cl, n, err := imapc.Open(in, true, 30*time.Second)
47	if err != nil {
48		return c.fail(protocol.ExitFailure, "%s: %v", in.Addr(), err)
49	}
50	defer cl.Close()
51	unseen, err := cl.Unseen()
52	if err != nil {
53		return c.fail(protocol.ExitFailure, "%s: %v", in.Addr(), err)
54	}
55	d := out{Enabled: true, Server: in.Addr(), Mailbox: in.MailboxName(), Messages: n, Unseen: len(unseen)}
56	if in.TrustedAuthservID == "" {
57		d.Warning = unauthenticatedWarning
58		fmt.Fprintln(c.Stderr, "warning: "+d.Warning)
59	}
60	return c.emit(d, func(w io.Writer) {
61		c.view(w).fields(
62			"server", d.Server,
63			"mailbox", d.Mailbox,
64			"messages", fmt.Sprintf("%d", d.Messages),
65			"unseen", fmt.Sprintf("%d", d.Unseen),
66		)
67	})
68}