mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-17 23:56:56 +00:00
Implement deleted flag GODT-461
This commit is contained in:
@ -173,9 +173,8 @@ func (im *imapMailbox) Check() error {
|
||||
|
||||
// Expunge permanently removes all messages that have the \Deleted flag set
|
||||
// from the currently selected mailbox.
|
||||
// Our messages do not have \Deleted flag, nothing to do here.
|
||||
func (im *imapMailbox) Expunge() error {
|
||||
return nil
|
||||
return im.storeMailbox.RemoveDeleted()
|
||||
}
|
||||
|
||||
func (im *imapMailbox) ListQuotas() ([]string, error) {
|
||||
|
||||
@ -220,6 +220,9 @@ func (im *imapMailbox) getMessage(storeMessage storeMessageProvider, items []ima
|
||||
}
|
||||
case imap.FetchFlags:
|
||||
msg.Flags = message.GetFlags(m)
|
||||
if storeMessage.IsMarkedDeleted() {
|
||||
msg.Flags = append(msg.Flags, imap.DeletedFlag)
|
||||
}
|
||||
case imap.FetchInternalDate:
|
||||
msg.InternalDate = time.Unix(m.Time, 0)
|
||||
case imap.FetchRFC822Size:
|
||||
@ -237,26 +240,30 @@ func (im *imapMailbox) getMessage(storeMessage storeMessageProvider, items []ima
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
s := item
|
||||
|
||||
var section *imap.BodySectionName
|
||||
if section, err = imap.ParseBodySectionName(s); err != nil {
|
||||
err = nil // Ignore error
|
||||
break
|
||||
}
|
||||
|
||||
var literal imap.Literal
|
||||
if literal, err = im.getMessageBodySection(storeMessage, section); err != nil {
|
||||
if err = im.getLiteralForSection(item, msg, storeMessage); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
msg.Body[section] = literal
|
||||
}
|
||||
}
|
||||
|
||||
return msg, err
|
||||
}
|
||||
|
||||
func (im *imapMailbox) getLiteralForSection(itemSection imap.FetchItem, msg *imap.Message, storeMessage storeMessageProvider) error {
|
||||
section, err := imap.ParseBodySectionName(itemSection)
|
||||
if err != nil { // Ignore error
|
||||
return nil
|
||||
}
|
||||
|
||||
var literal imap.Literal
|
||||
if literal, err = im.getMessageBodySection(storeMessage, section); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg.Body[section] = literal
|
||||
return nil
|
||||
}
|
||||
|
||||
func (im *imapMailbox) getBodyStructure(storeMessage storeMessageProvider) (
|
||||
structure *message.BodyStructure,
|
||||
bodyReader *bytes.Reader, err error,
|
||||
|
||||
@ -97,7 +97,11 @@ func (im *imapMailbox) setFlags(messageIDs, flags []string) error {
|
||||
}
|
||||
|
||||
if deleted {
|
||||
if err := im.storeMailbox.DeleteMessages(messageIDs); err != nil {
|
||||
if err := im.storeMailbox.MarkMessagesDeleted(messageIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := im.storeMailbox.MarkMessagesUndeleted(messageIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -145,11 +149,15 @@ func (im *imapMailbox) addOrRemoveFlags(operation imap.FlagsOp, messageIDs, flag
|
||||
}
|
||||
}
|
||||
case imap.DeletedFlag:
|
||||
if operation == imap.RemoveFlags {
|
||||
break // Nothing to do, no message has the \Deleted flag.
|
||||
}
|
||||
if err := im.storeMailbox.DeleteMessages(messageIDs); err != nil {
|
||||
return err
|
||||
switch operation {
|
||||
case imap.AddFlags:
|
||||
if err := im.storeMailbox.MarkMessagesDeleted(messageIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
case imap.RemoveFlags:
|
||||
if err := im.storeMailbox.MarkMessagesUndeleted(messageIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case imap.AnsweredFlag, imap.DraftFlag, imap.RecentFlag:
|
||||
// Not supported.
|
||||
@ -349,6 +357,9 @@ func (im *imapMailbox) SearchMessages(isUID bool, criteria *imap.SearchCriteria)
|
||||
if !m.Has(pmapi.FlagOpened) {
|
||||
messageFlagsMap[imap.RecentFlag] = true
|
||||
}
|
||||
if storeMessage.IsMarkedDeleted() {
|
||||
messageFlagsMap[imap.DeletedFlag] = true
|
||||
}
|
||||
|
||||
flagMatch := true
|
||||
for _, flag := range criteria.WithFlags {
|
||||
|
||||
@ -83,8 +83,10 @@ type storeMailboxProvider interface {
|
||||
MarkMessagesUnread(apiID []string) error
|
||||
MarkMessagesStarred(apiID []string) error
|
||||
MarkMessagesUnstarred(apiID []string) error
|
||||
MarkMessagesDeleted(apiID []string) error
|
||||
MarkMessagesUndeleted(apiID []string) error
|
||||
ImportMessage(msg *pmapi.Message, body []byte, labelIDs []string) error
|
||||
DeleteMessages(apiID []string) error
|
||||
RemoveDeleted() error
|
||||
}
|
||||
|
||||
type storeMessageProvider interface {
|
||||
@ -92,6 +94,7 @@ type storeMessageProvider interface {
|
||||
UID() (uint32, error)
|
||||
SequenceNumber() (uint32, error)
|
||||
Message() *pmapi.Message
|
||||
IsMarkedDeleted() bool
|
||||
|
||||
SetSize(int64) error
|
||||
SetContentTypeAndHeader(string, mail.Header) error
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
package uidplus
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
@ -120,11 +121,51 @@ func (os *OrderedSeq) String() string {
|
||||
// If not implemented it would cause harmless IMAP error.
|
||||
//
|
||||
// This overrides the standard EXPUNGE functionality.
|
||||
type UIDExpunge struct{}
|
||||
type UIDExpunge struct {
|
||||
expunge *server.Expunge
|
||||
seqset *imap.SeqSet
|
||||
}
|
||||
|
||||
func (e *UIDExpunge) Parse(fields []interface{}) error { log.Traceln("parse", fields); return nil }
|
||||
func (e *UIDExpunge) Handle(conn server.Conn) error { log.Traceln("handle"); return nil }
|
||||
func (e *UIDExpunge) UidHandle(conn server.Conn) error { log.Traceln("uid handle"); return nil } //nolint[golint]
|
||||
func newUIDExpunge() *UIDExpunge {
|
||||
return &UIDExpunge{expunge: &server.Expunge{}}
|
||||
}
|
||||
|
||||
func (e *UIDExpunge) Parse(fields []interface{}) error {
|
||||
if len(fields) < 1 { // asuming no UID
|
||||
return e.expunge.Parse(fields)
|
||||
}
|
||||
|
||||
var err error
|
||||
if seqset, ok := fields[0].(string); !ok {
|
||||
return errors.New("sequence set must be an atom")
|
||||
} else if e.seqset, err = imap.ParseSeqSet(seqset); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *UIDExpunge) Handle(conn server.Conn) error {
|
||||
log.Traceln("handle")
|
||||
return e.expunge.Handle(conn)
|
||||
}
|
||||
func (e *UIDExpunge) UidHandle(conn server.Conn) error { //nolint[golint]
|
||||
log.Traceln("uid handle")
|
||||
// RFC4315#section-2.1
|
||||
// The UID EXPUNGE command permanently removes all messages that both
|
||||
// have the \Deleted flag set and have a UID that is included in the
|
||||
// specified sequence set from the currently selected mailbox. If a
|
||||
// message either does not have the \Deleted flag set or has a UID
|
||||
// that is not included in the specified sequence set, it is not
|
||||
// affected.
|
||||
//
|
||||
// NOTE missing implementation: It will probably need mailbox interface
|
||||
// change: ExpungeUIDs(seqSet) not sure how to combine with original
|
||||
// e.expunge.Handle().
|
||||
//
|
||||
// Current implementation deletes all marked as deleted.
|
||||
return e.expunge.Handle(conn)
|
||||
}
|
||||
|
||||
type extension struct{}
|
||||
|
||||
@ -143,7 +184,7 @@ func (ext *extension) Capabilities(c server.Conn) []string {
|
||||
func (ext *extension) Command(name string) server.HandlerFactory {
|
||||
if name == "EXPUNGE" {
|
||||
return func() server.Handler {
|
||||
return &UIDExpunge{}
|
||||
return newUIDExpunge()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user