Refactoring; consume listing response

This commit is contained in:
Drew DeVault 2018-02-01 19:54:19 -05:00
parent cc03f6f4c8
commit d603bbe2ce
4 changed files with 57 additions and 53 deletions

View File

@ -31,12 +31,20 @@ func NewAccountTab(conf *config.AccountConfig,
Worker: work, Worker: work,
logger: logger, logger: logger,
} }
acc.Worker.PostAction(types.Configure{Config: conf}, nil) acc.Worker.PostAction(&types.Configure{Config: conf}, nil)
acc.Worker.PostAction(types.Connect{}, func(msg types.WorkerMessage) { acc.Worker.PostAction(&types.Connect{}, func(msg types.WorkerMessage) {
if _, ok := msg.(types.Ack); ok { switch msg := msg.(type) {
case *types.Done:
acc.logger.Println("Connected.") acc.logger.Println("Connected.")
acc.Worker.PostAction(types.ListDirectories{}, nil) acc.Worker.PostAction(&types.ListDirectories{}, nil)
} else { case *types.CertificateApprovalRequest:
// TODO: Ask the user
acc.logger.Println("Approving certificate")
acc.Worker.PostAction(&types.ApproveCertificate{
Message: types.RespondTo(msg),
Approved: true,
}, nil)
default:
acc.logger.Println("Connection failed.") acc.logger.Println("Connection failed.")
} }
}) })
@ -72,18 +80,17 @@ func (acc *AccountTab) GetChannel() chan types.WorkerMessage {
func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) { func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) {
msg = acc.Worker.ProcessMessage(msg) msg = acc.Worker.ProcessMessage(msg)
switch msg.(type) { switch msg := msg.(type) {
case types.Ack: case *types.Done:
case types.Unsupported: case *types.CertificateApprovalRequest:
case *types.Unsupported:
// no-op // no-op
case types.ApproveCertificate: case *types.Error:
// TODO: Ask the user acc.logger.Printf("Error: %v\n", msg.Error)
acc.logger.Println("Approving certificate") case *types.Directory:
acc.Worker.PostAction(types.Ack{ acc.logger.Printf("Directory: %s\n", msg.Name)
Message: types.RespondTo(msg),
}, nil)
default: default:
acc.Worker.PostAction(types.Unsupported{ acc.Worker.PostAction(&types.Unsupported{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
}, nil) }, nil)
} }

View File

@ -6,7 +6,7 @@ import (
"git.sr.ht/~sircmpwn/aerc2/worker/types" "git.sr.ht/~sircmpwn/aerc2/worker/types"
) )
func (imapw *IMAPWorker) handleListDirectories(msg types.ListDirectories) { func (imapw *IMAPWorker) handleListDirectories(msg *types.ListDirectories) {
mailboxes := make(chan *imap.MailboxInfo) mailboxes := make(chan *imap.MailboxInfo)
done := make(chan error, 1) done := make(chan error, 1)
imapw.worker.Logger.Println("Listing mailboxes") imapw.worker.Logger.Println("Listing mailboxes")
@ -18,18 +18,22 @@ func (imapw *IMAPWorker) handleListDirectories(msg types.ListDirectories) {
select { select {
case err := <-done: case err := <-done:
if err != nil { if err != nil {
imapw.worker.PostMessage(types.Error{ imapw.worker.PostMessage(&types.Error{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Error: err, Error: err,
}, nil) }, nil)
} else { } else {
imapw.worker.PostMessage( imapw.worker.PostMessage(
types.Done{types.RespondTo(msg)}, nil) &types.Done{types.RespondTo(msg)}, nil)
} }
return return
case mbox := <-mailboxes: case mbox := <-mailboxes:
if mbox != nil { if mbox != nil {
imapw.worker.Logger.Printf("%v\n", mbox.Name) imapw.worker.PostMessage(&types.Directory{
Message: types.RespondTo(msg),
Name: mbox.Name,
Attributes: mbox.Attributes,
}, nil)
} }
} }
} }

View File

@ -54,7 +54,7 @@ func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
pool.AddCert(cert) pool.AddCert(cert)
} }
request := types.ApproveCertificate{ request := &types.CertificateApprovalRequest{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
CertPool: pool, CertPool: pool,
} }
@ -62,25 +62,25 @@ func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
response := <-w.worker.Actions response := <-w.worker.Actions
if response.InResponseTo() != request { if response.InResponseTo() != request {
return fmt.Errorf("Expected UI to answer cert request") return fmt.Errorf("Expected UI to respond to cert request")
} }
switch response.(type) { if approval, ok := response.(*types.ApproveCertificate); !ok {
case types.Ack: return fmt.Errorf("Expected UI to send certificate approval")
} else {
if approval.Approved {
return nil return nil
case types.Disconnect: } else {
return fmt.Errorf("UI rejected certificate") return fmt.Errorf("UI rejected certificate")
default: }
return fmt.Errorf("Expected UI to answer cert request")
} }
} }
} }
func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
switch msg := msg.(type) { switch msg := msg.(type) {
case types.Ping: case *types.Unsupported:
case types.Unsupported:
// No-op // No-op
case types.Configure: case *types.Configure:
u, err := url.Parse(msg.Config.Source) u, err := url.Parse(msg.Config.Source)
if err != nil { if err != nil {
return err return err
@ -99,14 +99,14 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.config.scheme = u.Scheme w.config.scheme = u.Scheme
w.config.user = u.User w.config.user = u.User
case types.Connect: case *types.Connect:
var ( var (
c *client.Client c *client.Client
err error err error
) )
tlsConfig := &tls.Config{ tlsConfig := &tls.Config{
InsecureSkipVerify: true, InsecureSkipVerify: true,
VerifyPeerCertificate: w.verifyPeerCert(&msg), VerifyPeerCertificate: w.verifyPeerCert(msg),
} }
switch w.config.scheme { switch w.config.scheme {
case "imap": case "imap":
@ -146,7 +146,8 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
c.Updates = w.updates c.Updates = w.updates
w.client = &imapClient{c, idle.NewClient(c)} w.client = &imapClient{c, idle.NewClient(c)}
case types.ListDirectories: w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.ListDirectories:
w.handleListDirectories(msg) w.handleListDirectories(msg)
default: default:
return errUnsupported return errUnsupported
@ -160,18 +161,14 @@ func (w *IMAPWorker) Run() {
case msg := <-w.worker.Actions: case msg := <-w.worker.Actions:
msg = w.worker.ProcessAction(msg) msg = w.worker.ProcessAction(msg)
if err := w.handleMessage(msg); err == errUnsupported { if err := w.handleMessage(msg); err == errUnsupported {
w.worker.PostMessage(types.Unsupported{ w.worker.PostMessage(&types.Unsupported{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
}, nil) }, nil)
} else if err != nil { } else if err != nil {
w.worker.PostMessage(types.Error{ w.worker.PostMessage(&types.Error{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Error: err, Error: err,
}, nil) }, nil)
} else {
w.worker.PostMessage(types.Ack{
Message: types.RespondTo(msg),
}, nil)
} }
case update := <-w.updates: case update := <-w.updates:
w.worker.Logger.Printf("(= %T", update) w.worker.Logger.Printf("(= %T", update)

View File

@ -26,11 +26,6 @@ func (m Message) InResponseTo() WorkerMessage {
// Meta-messages // Meta-messages
// TODO: Figure out a nice way of merging Ack and Done
type Ack struct {
Message
}
type Done struct { type Done struct {
Message Message
} }
@ -46,8 +41,9 @@ type Unsupported struct {
// Actions // Actions
type Ping struct { type ApproveCertificate struct {
Message Message
Approved bool
} }
type Configure struct { type Configure struct {
@ -69,13 +65,13 @@ type ListDirectories struct {
// Messages // Messages
type Directory struct { type CertificateApprovalRequest struct {
Message
Name *string
}
// Respond with an Ack to approve or Disconnect to reject
type ApproveCertificate struct {
Message Message
CertPool *x509.CertPool CertPool *x509.CertPool
} }
type Directory struct {
Message
Attributes []string
Name string
}