imap: implement basic User.ListMailboxes and User.GetMailbox
This commit is contained in:
parent
e7302dd4c4
commit
7020ee3623
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
imapserver "github.com/emersion/go-imap/server"
|
imapserver "github.com/emersion/go-imap/server"
|
||||||
|
imapspacialuse "github.com/emersion/go-imap-specialuse"
|
||||||
"github.com/emersion/go-smtp"
|
"github.com/emersion/go-smtp"
|
||||||
"github.com/howeyc/gopass"
|
"github.com/howeyc/gopass"
|
||||||
|
|
||||||
|
@ -162,6 +163,7 @@ func main() {
|
||||||
s := imapserver.New(be)
|
s := imapserver.New(be)
|
||||||
s.Addr = "127.0.0.1:" + port
|
s.Addr = "127.0.0.1:" + port
|
||||||
s.AllowInsecureAuth = true // TODO: remove this
|
s.AllowInsecureAuth = true // TODO: remove this
|
||||||
|
s.Enable(imapspacialuse.NewExtension())
|
||||||
|
|
||||||
log.Println("Starting IMAP server at", s.Addr)
|
log.Println("Starting IMAP server at", s.Addr)
|
||||||
log.Fatal(s.ListenAndServe())
|
log.Fatal(s.ListenAndServe())
|
||||||
|
|
|
@ -27,12 +27,7 @@ func (be *backend) Login(username, password string) (imapbackend.User, error) {
|
||||||
|
|
||||||
// TODO: decrypt private keys in u.Addresses
|
// TODO: decrypt private keys in u.Addresses
|
||||||
|
|
||||||
return &user{
|
return newUser(c, u, privateKeys)
|
||||||
username: username,
|
|
||||||
c: c,
|
|
||||||
u: u,
|
|
||||||
privateKeys: privateKeys,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(sessions *auth.Manager) imapbackend.Backend {
|
func New(sessions *auth.Manager) imapbackend.Backend {
|
||||||
|
|
|
@ -6,8 +6,12 @@ import (
|
||||||
"github.com/emersion/go-imap"
|
"github.com/emersion/go-imap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const delimiter = "/"
|
||||||
|
|
||||||
type mailbox struct {
|
type mailbox struct {
|
||||||
name string
|
name string
|
||||||
|
label string
|
||||||
|
flags []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mbox *mailbox) Name() string {
|
func (mbox *mailbox) Name() string {
|
||||||
|
@ -15,11 +19,35 @@ func (mbox *mailbox) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mbox *mailbox) Info() (*imap.MailboxInfo, error) {
|
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) {
|
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 {
|
func (mbox *mailbox) SetSubscribed(subscribed bool) error {
|
||||||
|
|
53
imap/user.go
53
imap/user.go
|
@ -2,28 +2,73 @@ package imap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
|
"github.com/emersion/go-imap"
|
||||||
imapbackend "github.com/emersion/go-imap/backend"
|
imapbackend "github.com/emersion/go-imap/backend"
|
||||||
|
"github.com/emersion/go-imap-specialuse"
|
||||||
|
|
||||||
"github.com/emersion/hydroxide/protonmail"
|
"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 {
|
type user struct {
|
||||||
username string
|
|
||||||
c *protonmail.Client
|
c *protonmail.Client
|
||||||
u *protonmail.User
|
u *protonmail.User
|
||||||
privateKeys openpgp.EntityList
|
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 {
|
func (u *user) Username() string {
|
||||||
return u.username
|
return u.u.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *user) ListMailboxes(subscribed bool) ([]imapbackend.Mailbox, error) {
|
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) {
|
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 {
|
func (u *user) CreateMailbox(name string) error {
|
||||||
|
|
|
@ -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"
|
||||||
|
)
|
Loading…
Reference in New Issue