Added IMAP extension MOVE with UIDPLUS support

This commit is contained in:
Michal Horejsek 2020-04-16 14:32:40 +02:00 committed by Jakub Cuth
parent 0c7a328165
commit e166748270
7 changed files with 37 additions and 45 deletions

View File

@ -5,6 +5,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
## Unpublished
### Added
* IMAP extension MOVE with UIDPLUS support
* IMAP extension Unselect
* More logs about event loop activity

1
go.mod
View File

@ -31,6 +31,7 @@ require (
github.com/danieljoos/wincred v1.0.2 // indirect
github.com/emersion/go-imap-appendlimit v0.0.0-20160923165328-beeb382f2a42
github.com/emersion/go-imap-idle v0.0.0-20161227184850-e03ba1e0ed89
github.com/emersion/go-imap-move v0.0.0-20161227183138-88aef42b0f1d
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62
github.com/emersion/go-imap-unselect v0.0.0-20161227183655-1e6dc73ac8fe
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b

4
go.sum
View File

@ -65,6 +65,10 @@ github.com/emersion/go-imap-appendlimit v0.0.0-20160923165328-beeb382f2a42 h1:3T
github.com/emersion/go-imap-appendlimit v0.0.0-20160923165328-beeb382f2a42/go.mod h1:ikgISoP7pRAolqsVP64yMteJa2FIpS6ju88eBT6K1yQ=
github.com/emersion/go-imap-idle v0.0.0-20161227184850-e03ba1e0ed89 h1:AzbVhcrxgJO5MfSvzG5q4IfrYVm0Jw4AHNPz47+DiR0=
github.com/emersion/go-imap-idle v0.0.0-20161227184850-e03ba1e0ed89/go.mod h1:o14zPKCmEH5WC1vU5SdPoZGgNvQx7zzKSnxPQlobo78=
github.com/emersion/go-imap-move v0.0.0-20161227173100-88aef42b0f1d h1:STRZFC+5HZITdsSFkhFfyYRb+tkiTwhxFz3sRW1lYjk=
github.com/emersion/go-imap-move v0.0.0-20161227173100-88aef42b0f1d/go.mod h1:QuMaZcKFDVI0yCrnAbPLfbwllz1wtOrZH8/vZ5yzp4w=
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342 h1:5p1t3e1PomYgLWwEwhwEU5kVBwcyAcVrOpexv8AeZx0=
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342/go.mod h1:QuMaZcKFDVI0yCrnAbPLfbwllz1wtOrZH8/vZ5yzp4w=
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62 h1:4ZAfwfc8aDlj26kkEap1UDSwwDnJp9Ie8Uj1MSXAkPk=
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62/go.mod h1:/nybxhI8kXom8Tw6BrHMl42usALvka6meORflnnYwe4=
github.com/emersion/go-imap-unselect v0.0.0-20161227183655-1e6dc73ac8fe h1:2R2XpJkmbyy7PcSjnCPOnNfu+GuRzgWR9U2+j/d1O+0=

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// Code generated by ./credits.sh at Thu Apr 9 13:39:29 CEST 2020. DO NOT EDIT.
// Code generated by ./credits.sh at Thu Apr 16 13:43:04 CEST 2020. DO NOT EDIT.
package bridge
const Credits = "github.com/0xAX/notificator;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-imap-quota;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/andybalholm/cascadia;github.com/certifi/gocertifi;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/danieljoos/wincred;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/raven-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/jhillyerd/enmime;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"
const Credits = "github.com/0xAX/notificator;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-imap-quota;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/andybalholm/cascadia;github.com/certifi/gocertifi;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/danieljoos/wincred;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/raven-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/jhillyerd/enmime;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"

View File

@ -102,6 +102,21 @@ func (im *imapMailbox) CopyMessages(uid bool, seqSet *imap.SeqSet, targetLabel s
// Called from go-imap in goroutines - we need to handle panics for each function.
defer im.panicHandler.HandlePanic()
return im.labelMessages(uid, seqSet, targetLabel, false)
}
// MoveMessages adds dest's label and removes this mailbox' label from each message.
//
// This should not be used until MOVE extension has option to send UIDPLUS
// responses.
func (im *imapMailbox) MoveMessages(uid bool, seqSet *imap.SeqSet, targetLabel string) error {
// Called from go-imap in goroutines - we need to handle panics for each function.
defer im.panicHandler.HandlePanic()
return im.labelMessages(uid, seqSet, targetLabel, true)
}
func (im *imapMailbox) labelMessages(uid bool, seqSet *imap.SeqSet, targetLabel string, move bool) error {
messageIDs, err := im.apiIDsFromSeqSet(uid, seqSet)
if err != nil || len(messageIDs) == 0 {
return err
@ -111,40 +126,24 @@ func (im *imapMailbox) CopyMessages(uid bool, seqSet *imap.SeqSet, targetLabel s
// messages can be removed from source during labeling (e.g. folder1 -> folder2).
sourceSeqSet := im.storeMailbox.GetUIDList(messageIDs)
targetStoreMBX, err := im.storeAddress.GetMailbox(targetLabel)
targetStoreMailbox, err := im.storeAddress.GetMailbox(targetLabel)
if err != nil {
return err
}
if err = targetStoreMBX.LabelMessages(messageIDs); err != nil {
return err
}
targetSeqSet := targetStoreMBX.GetUIDList(messageIDs)
return uidplus.CopyResponse(im.storeMailbox.UIDValidity(), sourceSeqSet, targetSeqSet)
}
// MoveMessages adds dest's label and removes this mailbox' label from each message.
//
// This should not be used until MOVE extension has option to send UIDPLUS
// responses.
func (im *imapMailbox) MoveMessages(uid bool, seqSet *imap.SeqSet, newLabel string) error {
// Called from go-imap in goroutines - we need to handle panics for each function.
defer im.panicHandler.HandlePanic()
messageIDs, err := im.apiIDsFromSeqSet(uid, seqSet)
if err != nil || len(messageIDs) == 0 {
return err
}
storeMailbox, err := im.storeAddress.GetMailbox(newLabel)
if err != nil {
return err
}
// Label messages first to not loss them. If message is only in trash and we unlabel
// it, it will be removed completely and we cannot label it back.
if err := storeMailbox.LabelMessages(messageIDs); err != nil {
if err := targetStoreMailbox.LabelMessages(messageIDs); err != nil {
return err
}
return im.storeMailbox.UnlabelMessages(messageIDs)
if move {
if err := im.storeMailbox.UnlabelMessages(messageIDs); err != nil {
return err
}
}
targetSeqSet := targetStoreMailbox.GetUIDList(messageIDs)
return uidplus.CopyResponse(targetStoreMailbox.UIDValidity(), sourceSeqSet, targetSeqSet)
}
// SearchMessages searches messages. The returned list must contain UIDs if

View File

@ -32,6 +32,7 @@ import (
"github.com/emersion/go-imap"
imapappendlimit "github.com/emersion/go-imap-appendlimit"
imapidle "github.com/emersion/go-imap-idle"
imapmove "github.com/emersion/go-imap-move"
imapquota "github.com/emersion/go-imap-quota"
imapspecialuse "github.com/emersion/go-imap-specialuse"
imapunselect "github.com/emersion/go-imap-unselect"
@ -96,7 +97,7 @@ func NewIMAPServer(debugClient, debugServer bool, port int, tls *tls.Config, ima
s.Enable(
imapidle.NewExtension(),
//imapmove.NewExtension(), // extension is not fully implemented: if UIDPLUS exists it MUST return COPYUID and EXPUNGE continuous responses
imapmove.NewExtension(),
imapspecialuse.NewExtension(),
imapid.NewExtension(serverID),
imapquota.NewExtension(),

View File

@ -9,9 +9,8 @@ Feature: IMAP move messages
And there is IMAP client logged in as "user"
And there is IMAP client selected in "INBOX"
@ignore
Scenario: Move message
When IMAP client moves messages "1" to "Folders/mbox"
When IMAP client moves messages "2" to "Folders/mbox"
Then IMAP response is "OK"
And mailbox "INBOX" for "user" has messages
| from | to | subject |
@ -20,7 +19,6 @@ Feature: IMAP move messages
| from | to | subject |
| john.doe@mail.com | user@pm.me | foo |
@ignore
Scenario: Move all messages
When IMAP client moves messages "1:*" to "Folders/mbox"
Then IMAP response is "OK"
@ -30,20 +28,8 @@ Feature: IMAP move messages
| john.doe@mail.com | user@pm.me | foo |
| jane.doe@mail.com | name@pm.me | bar |
@ignore
Scenario: Move message to All Mail
When IMAP client moves messages "1" to "All Mail"
Then IMAP response is "OK"
And mailbox "INBOX" for "user" has messages
| from | to | subject |
| jane.doe@mail.com | name@pm.me | bar |
And mailbox "All Mail" for "user" has messages
| from | to | subject |
| john.doe@mail.com | user@pm.me | foo |
@ignore
Scenario: Move message from All Mail is not possible
When IMAP client moves messages "1" to "Folders/mbox"
When IMAP client moves messages "2" to "Folders/mbox"
Then IMAP response is "OK"
And mailbox "All Mail" for "user" has messages
| from | to | subject |