This commit is contained in:
emersion 2018-10-21 12:15:20 +02:00
parent 6524fc1913
commit 6bd8ce1b6e
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
13 changed files with 95 additions and 95 deletions

View File

@ -11,16 +11,16 @@ import (
"time"
imapmove "github.com/emersion/go-imap-move"
imapserver "github.com/emersion/go-imap/server"
imapspacialuse "github.com/emersion/go-imap-specialuse"
imapserver "github.com/emersion/go-imap/server"
"github.com/emersion/go-smtp"
"github.com/howeyc/gopass"
"github.com/emersion/hydroxide/auth"
"github.com/emersion/hydroxide/carddav"
"github.com/emersion/hydroxide/events"
"github.com/emersion/hydroxide/protonmail"
imapbackend "github.com/emersion/hydroxide/imap"
"github.com/emersion/hydroxide/protonmail"
smtpbackend "github.com/emersion/hydroxide/smtp"
)

View File

@ -13,7 +13,7 @@ const pollInterval = 30 * time.Second
type Receiver struct {
c *protonmail.Client
locker sync.Mutex
locker sync.Mutex
channels []chan<- *protonmail.Event
poll chan struct{}
@ -56,7 +56,7 @@ func (r *Receiver) Poll() {
type Manager struct {
receivers map[string]*Receiver
locker sync.Mutex
locker sync.Mutex
}
func NewManager() *Manager {
@ -76,9 +76,9 @@ func (m *Manager) Register(c *protonmail.Client, username string, ch chan<- *pro
r.locker.Unlock()
} else {
r = &Receiver{
c: c,
c: c,
channels: []chan<- *protonmail.Event{ch},
poll: make(chan struct{}),
poll: make(chan struct{}),
}
go func() {

View File

@ -12,9 +12,9 @@ import (
var errNotYetImplemented = errors.New("not yet implemented")
type backend struct {
sessions *auth.Manager
sessions *auth.Manager
eventsManager *events.Manager
updates chan imapbackend.Update
updates chan imapbackend.Update
}
func (be *backend) Login(username, password string) (imapbackend.User, error) {

View File

@ -51,7 +51,7 @@ func mailboxDeleteMessage(b *bolt.Bucket, apiID string) (seqNum uint32, err erro
type Mailbox struct {
labelID string
u *User
u *User
}
func (mbox *Mailbox) bucket(tx *bolt.Tx) (*bolt.Bucket, error) {

View File

@ -13,7 +13,7 @@ var ErrNotFound = errors.New("message not found in local database")
var (
mailboxesBucket = []byte("mailboxes")
messagesBucket = []byte("messages")
messagesBucket = []byte("messages")
)
func userMessage(b *bolt.Bucket, apiID string) (*protonmail.Message, error) {
@ -74,7 +74,7 @@ func (u *User) Mailbox(labelID string) (*Mailbox, error) {
func (u *User) Message(apiID string) (*protonmail.Message, error) {
var msg *protonmail.Message
err := u.db.View(func (tx *bolt.Tx) error {
err := u.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket(messagesBucket)
if b == nil {
return ErrNotFound
@ -181,7 +181,7 @@ func (u *User) UpdateMessage(apiID string, update *protonmail.EventMessageUpdate
func (u *User) DeleteMessage(apiID string) (seqNums map[string]uint32, err error) {
seqNums = make(map[string]uint32)
err = u.db.Update(func(tx *bolt.Tx) error {
messages:= tx.Bucket(messagesBucket)
messages := tx.Bucket(messagesBucket)
if messages == nil {
return nil
}

View File

@ -17,18 +17,18 @@ import (
const delimiter = "/"
type mailbox struct {
name string
name string
label string
flags []string
u *user
u *user
db *database.Mailbox
initialized bool
initialized bool
initializedLock sync.Mutex
total, unread int
deleted map[string]struct{}
deleted map[string]struct{}
}
func (mbox *mailbox) Name() string {
@ -38,8 +38,8 @@ func (mbox *mailbox) Name() string {
func (mbox *mailbox) Info() (*imap.MailboxInfo, error) {
return &imap.MailboxInfo{
Attributes: append(mbox.flags, imap.NoInferiorsAttr),
Delimiter: delimiter,
Name: mbox.name,
Delimiter: delimiter,
Name: mbox.name,
}, nil
}
@ -89,9 +89,9 @@ func (mbox *mailbox) sync() error {
filter := &protonmail.MessageFilter{
PageSize: 150,
Label: mbox.label,
Sort: "ID",
Asc: true,
Label: mbox.label,
Sort: "ID",
Asc: true,
}
total := -1

View File

@ -54,8 +54,8 @@ func imapAddress(addr *protonmail.MessageAddress) *imap.Address {
return &imap.Address{
PersonalName: addr.Name,
MailboxName: parts[0],
HostName: parts[1],
MailboxName: parts[0],
HostName: parts[1],
}
}
@ -74,14 +74,14 @@ func fetchEnvelope(msg *protonmail.Message) *imap.Envelope {
}
return &imap.Envelope{
Date: time.Unix(msg.Time, 0),
Date: time.Unix(msg.Time, 0),
Subject: msg.Subject,
From: []*imap.Address{imapAddress(msg.Sender)},
From: []*imap.Address{imapAddress(msg.Sender)},
// TODO: Sender
ReplyTo: replyTo,
To: imapAddressList(msg.ToList),
Cc: imapAddressList(msg.CCList),
Bcc: imapAddressList(msg.BCCList),
To: imapAddressList(msg.ToList),
Cc: imapAddressList(msg.CCList),
Bcc: imapAddressList(msg.BCCList),
// TODO: InReplyTo
MessageId: messageID(msg),
}
@ -136,11 +136,11 @@ func (mbox *mailbox) fetchBodyStructure(msg *protonmail.Message, extended bool)
inlineType, inlineSubType := splitMIMEType(msg.MIMEType)
parts := []*imap.BodyStructure{
&imap.BodyStructure{
MIMEType: inlineType,
MIMEType: inlineType,
MIMESubType: inlineSubType,
Encoding: "quoted-printable",
Size: uint32(len(msg.Body)),
Extended: extended,
Encoding: "quoted-printable",
Size: uint32(len(msg.Body)),
Extended: extended,
Disposition: "inline",
},
}
@ -148,23 +148,23 @@ func (mbox *mailbox) fetchBodyStructure(msg *protonmail.Message, extended bool)
for _, att := range msg.Attachments {
attType, attSubType := splitMIMEType(att.MIMEType)
parts = append(parts, &imap.BodyStructure{
MIMEType: attType,
MIMESubType: attSubType,
Id: att.ContentID,
Encoding: "base64",
Size: uint32(att.Size),
Extended: extended,
Disposition: "attachment",
MIMEType: attType,
MIMESubType: attSubType,
Id: att.ContentID,
Encoding: "base64",
Size: uint32(att.Size),
Extended: extended,
Disposition: "attachment",
DispositionParams: map[string]string{"filename": att.Name},
})
}
return &imap.BodyStructure{
MIMEType: "multipart",
MIMEType: "multipart",
MIMESubType: "mixed",
// TODO: Params: map[string]string{"boundary": ...},
// TODO: Size
Parts: parts,
Parts: parts,
Extended: extended,
}, nil
}
@ -218,7 +218,7 @@ func attachmentHeader(att *protonmail.Attachment) message.Header {
func mailAddress(addr *protonmail.MessageAddress) *mail.Address {
return &mail.Address{
Name: addr.Name,
Name: addr.Name,
Address: addr.Address,
}
}

View File

@ -4,18 +4,18 @@ import (
"log"
"sync"
"golang.org/x/crypto/openpgp"
"github.com/emersion/go-imap"
imapbackend "github.com/emersion/go-imap/backend"
"github.com/emersion/go-imap-specialuse"
imapbackend "github.com/emersion/go-imap/backend"
"golang.org/x/crypto/openpgp"
"github.com/emersion/hydroxide/events"
"github.com/emersion/hydroxide/imap/database"
"github.com/emersion/hydroxide/protonmail"
)
var systemMailboxes = []struct{
name string
var systemMailboxes = []struct {
name string
label string
flags []string
}{
@ -34,25 +34,25 @@ type user struct {
u *protonmail.User
privateKeys openpgp.EntityList
db *database.User
db *database.User
eventsReceiver *events.Receiver
locker sync.Mutex
locker sync.Mutex
mailboxes map[string]*mailbox
done chan<- struct{}
done chan<- struct{}
eventSent chan struct{}
}
func newUser(be *backend, c *protonmail.Client, u *protonmail.User, privateKeys openpgp.EntityList) (*user, error) {
uu := &user{
c: c,
u: u,
c: c,
u: u,
privateKeys: privateKeys,
eventSent: make(chan struct{}),
eventSent: make(chan struct{}),
}
db, err := database.Open(u.Name+".db")
db, err := database.Open(u.Name + ".db")
if err != nil {
return nil, err
}
@ -84,11 +84,11 @@ func (u *user) initMailboxes() error {
}
u.mailboxes[data.label] = &mailbox{
name: data.name,
label: data.label,
flags: data.flags,
u: u,
db: mboxDB,
name: data.name,
label: data.label,
flags: data.flags,
u: u,
db: mboxDB,
deleted: make(map[string]struct{}),
}
}

View File

@ -1,9 +1,9 @@
package protonmail
import (
"io"
"crypto"
"hash"
"io"
"time"
"golang.org/x/crypto/openpgp"

View File

@ -13,8 +13,8 @@ const (
)
type Event struct {
ID string `json:"EventID"`
Refresh EventRefresh
ID string `json:"EventID"`
Refresh EventRefresh
Messages []*EventMessage
Contacts []*EventContact
//ContactEmails
@ -41,8 +41,8 @@ const (
)
type EventMessage struct {
ID string
Action EventAction
ID string
Action EventAction
// Only populated for EventCreate
Created *Message

View File

@ -143,26 +143,26 @@ func (msg *Message) Encrypt(to []*openpgp.Entity, signed *openpgp.Entity) (plain
}
type MessageFilter struct {
Page int
Page int
PageSize int
Limit int
Limit int
Label string
Sort string
Asc bool
Begin int64
End int64
Keyword string
To string
From string
Subject string
Attachments *bool
Starred *bool
Unread *bool
Label string
Sort string
Asc bool
Begin int64
End int64
Keyword string
To string
From string
Subject string
Attachments *bool
Starred *bool
Unread *bool
Conversation string
AddressID string
ID []string
ExternalID string
AddressID string
ID []string
ExternalID string
}
func (c *Client) ListMessages(filter *MessageFilter) (total int, messages []*Message, err error) {
@ -202,7 +202,7 @@ func (c *Client) ListMessages(filter *MessageFilter) (total int, messages []*Mes
var respData struct {
resp
Total int
Total int
Messages []*Message
}
if err := c.doJSON(req, &respData); err != nil {
@ -214,8 +214,8 @@ func (c *Client) ListMessages(filter *MessageFilter) (total int, messages []*Mes
type MessageCount struct {
LabelID string
Total int
Unread int
Total int
Unread int
}
func (c *Client) CountMessages(address string) ([]*MessageCount, error) {
@ -339,7 +339,7 @@ func (c *Client) UndeleteMessages(ids []string) error {
func (c *Client) LabelMessages(labelID string, ids []string) error {
reqData := struct {
LabelID string
IDs []string
IDs []string
}{labelID, ids}
req, err := c.newJSONRequest(http.MethodPut, "/messages/label", &reqData)
if err != nil {
@ -353,7 +353,7 @@ func (c *Client) LabelMessages(labelID string, ids []string) error {
func (c *Client) UnlabelMessages(labelID string, ids []string) error {
reqData := struct {
LabelID string
IDs []string
IDs []string
}{labelID, ids}
req, err := c.newJSONRequest(http.MethodPut, "/messages/unlabel", &reqData)
if err != nil {
@ -412,8 +412,8 @@ type MessagePackageSet struct {
}
type MessageBodyKey struct {
Algorithm string
Key string
Algorithm string
Key string
}
func NewMessagePackageSet(attachmentKeys map[string]*packet.EncryptedKey) *MessagePackageSet {
@ -493,7 +493,7 @@ func (set *MessagePackageSet) Encrypt(mimeType string, signed *openpgp.Entity) (
func (set *MessagePackageSet) AddCleartext(addr string) (*MessagePackage, error) {
pkg := &MessagePackage{
Type: MessagePackageCleartext,
Type: MessagePackageCleartext,
Signature: set.signature,
}
set.Addresses[addr] = pkg
@ -502,7 +502,7 @@ func (set *MessagePackageSet) AddCleartext(addr string) (*MessagePackage, error)
if set.BodyKey == nil || set.AttachmentKeys == nil {
set.BodyKey = &MessageBodyKey{
Algorithm: "aes256",
Key: base64.StdEncoding.EncodeToString(set.bodyKey.Key),
Key: base64.StdEncoding.EncodeToString(set.bodyKey.Key),
}
set.AttachmentKeys = make(map[string]string, len(set.attachmentKeys))

View File

@ -25,7 +25,7 @@ type resp struct {
func (r *resp) Err() error {
if err := r.RawAPIError; err != nil {
return &APIError{
Code: r.Code,
Code: r.Code,
Message: err.Message,
}
}
@ -41,7 +41,7 @@ type RawAPIError struct {
}
type APIError struct {
Code int
Code int
Message string
}

View File

@ -96,8 +96,8 @@ func (u *user) Send(from string, to []string, r io.Reader) error {
}
senderAddress := &protonmail.MessageAddress{
Address: fromAddr.Email,
Name: fromAddr.DisplayName,
Address: fromAddr.Email,
Name: fromAddr.DisplayName,
}
msg := &protonmail.Message{
@ -125,9 +125,9 @@ func (u *user) Send(from string, to []string, r io.Reader) error {
inReplyTo := inReplyToList[0].Address
filter := protonmail.MessageFilter{
Limit: 1,
Limit: 1,
ExternalID: inReplyTo,
AddressID: fromAddr.ID,
AddressID: fromAddr.ID,
}
total, msgs, err := u.c.ListMessages(&filter)
if err != nil {