imap: implement basic User.ListMailboxes and User.GetMailbox

This commit is contained in:
emersion 2017-12-03 16:05:24 +01:00
parent e7302dd4c4
commit 7020ee3623
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
5 changed files with 96 additions and 12 deletions

View File

@ -11,6 +11,7 @@ import (
"time"
imapserver "github.com/emersion/go-imap/server"
imapspacialuse "github.com/emersion/go-imap-specialuse"
"github.com/emersion/go-smtp"
"github.com/howeyc/gopass"
@ -162,6 +163,7 @@ func main() {
s := imapserver.New(be)
s.Addr = "127.0.0.1:" + port
s.AllowInsecureAuth = true // TODO: remove this
s.Enable(imapspacialuse.NewExtension())
log.Println("Starting IMAP server at", s.Addr)
log.Fatal(s.ListenAndServe())

View File

@ -27,12 +27,7 @@ func (be *backend) Login(username, password string) (imapbackend.User, error) {
// TODO: decrypt private keys in u.Addresses
return &user{
username: username,
c: c,
u: u,
privateKeys: privateKeys,
}, nil
return newUser(c, u, privateKeys)
}
func New(sessions *auth.Manager) imapbackend.Backend {

View File

@ -6,8 +6,12 @@ import (
"github.com/emersion/go-imap"
)
const delimiter = "/"
type mailbox struct {
name string
label string
flags []string
}
func (mbox *mailbox) Name() string {
@ -15,11 +19,35 @@ func (mbox *mailbox) Name() string {
}
func (mbox *mailbox) Info() (*imap.MailboxInfo, error) {
return nil, errNotYetImplemented // TODO
return &imap.MailboxInfo{
Attributes: append(mbox.flags, imap.NoInferiorsAttr),
Delimiter: delimiter,
Name: mbox.name,
}, nil
}
func (mbox *mailbox) Status(items []imap.StatusItem) (*imap.MailboxStatus, error) {
return nil, errNotYetImplemented // TODO
status := imap.NewMailboxStatus(mbox.name, items)
status.Flags = mbox.flags
status.PermanentFlags = []string{imap.SeenFlag, imap.AnsweredFlag, imap.FlaggedFlag, imap.DeletedFlag, imap.DraftFlag}
status.UnseenSeqNum = 0 // TODO
for _, name := range items {
switch name {
case imap.StatusMessages:
status.Messages = 0 // TODO
case imap.StatusUidNext:
status.UidNext = 1 // TODO
case imap.StatusUidValidity:
status.UidValidity = 1
case imap.StatusRecent:
status.Recent = 0 // TODO
case imap.StatusUnseen:
status.Unseen = 0 // TODO
}
}
return status, nil
}
func (mbox *mailbox) SetSubscribed(subscribed bool) error {

View File

@ -2,28 +2,73 @@ package imap
import (
"golang.org/x/crypto/openpgp"
"github.com/emersion/go-imap"
imapbackend "github.com/emersion/go-imap/backend"
"github.com/emersion/go-imap-specialuse"
"github.com/emersion/hydroxide/protonmail"
)
var systemMailboxes = []struct{
name string
label string
flags []string
}{
{imap.InboxName, protonmail.LabelInbox, nil},
{"All Mail", protonmail.LabelAllMail, []string{specialuse.All}},
{"Archive", protonmail.LabelArchive, []string{specialuse.Archive}},
{"Drafts", protonmail.LabelDraft, []string{specialuse.Drafts}},
{"Starred", protonmail.LabelStarred, []string{specialuse.Flagged}},
{"Spam", protonmail.LabelSpam, []string{specialuse.Junk}},
{"Sent", protonmail.LabelSent, []string{specialuse.Sent}},
{"Trash", protonmail.LabelTrash, []string{specialuse.Trash}},
}
type user struct {
username string
c *protonmail.Client
u *protonmail.User
privateKeys openpgp.EntityList
mailboxes map[string]*mailbox
}
func newUser(c *protonmail.Client, u *protonmail.User, privateKeys openpgp.EntityList) (*user, error) {
uu := &user{
c: c,
u: u,
privateKeys: privateKeys,
mailboxes: make(map[string]*mailbox),
}
for _, data := range systemMailboxes {
uu.mailboxes[data.name] = &mailbox{
name: data.name,
label: data.label,
flags: data.flags,
}
}
return uu, nil
}
func (u *user) Username() string {
return u.username
return u.u.Name
}
func (u *user) ListMailboxes(subscribed bool) ([]imapbackend.Mailbox, error) {
return nil, errNotYetImplemented // TODO
list := make([]imapbackend.Mailbox, 0, len(u.mailboxes))
for _, mbox := range u.mailboxes {
list = append(list, mbox)
}
return list, nil
}
func (u *user) GetMailbox(name string) (imapbackend.Mailbox, error) {
return &mailbox{}, errNotYetImplemented // TODO
if mbox, ok := u.mailboxes[name]; ok {
return mbox, nil
} else {
return nil, imapbackend.ErrNoSuchMailbox
}
}
func (u *user) CreateMailbox(name string) error {

14
protonmail/labels.go Normal file
View File

@ -0,0 +1,14 @@
package protonmail
const (
LabelInbox = "0"
LabelAllDraft = "1"
LabelAllSent = "2"
LabelTrash = "3"
LabelSpam = "4"
LabelAllMail = "5"
LabelArchive = "6"
LabelSent = "7"
LabelDraft = "8"
LabelStarred = "10"
)