Added IMAP extension MOVE with UIDPLUS support
This commit is contained in:
parent
0c7a328165
commit
e166748270
|
@ -5,6 +5,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
||||||
## Unpublished
|
## Unpublished
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
* IMAP extension MOVE with UIDPLUS support
|
||||||
* IMAP extension Unselect
|
* IMAP extension Unselect
|
||||||
* More logs about event loop activity
|
* More logs about event loop activity
|
||||||
|
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -31,6 +31,7 @@ require (
|
||||||
github.com/danieljoos/wincred v1.0.2 // indirect
|
github.com/danieljoos/wincred v1.0.2 // indirect
|
||||||
github.com/emersion/go-imap-appendlimit v0.0.0-20160923165328-beeb382f2a42
|
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-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-specialuse v0.0.0-20161227184202-ba031ced6a62
|
||||||
github.com/emersion/go-imap-unselect v0.0.0-20161227183655-1e6dc73ac8fe
|
github.com/emersion/go-imap-unselect v0.0.0-20161227183655-1e6dc73ac8fe
|
||||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b
|
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -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-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 h1:AzbVhcrxgJO5MfSvzG5q4IfrYVm0Jw4AHNPz47+DiR0=
|
||||||
github.com/emersion/go-imap-idle v0.0.0-20161227184850-e03ba1e0ed89/go.mod h1:o14zPKCmEH5WC1vU5SdPoZGgNvQx7zzKSnxPQlobo78=
|
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 h1:4ZAfwfc8aDlj26kkEap1UDSwwDnJp9Ie8Uj1MSXAkPk=
|
||||||
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62/go.mod h1:/nybxhI8kXom8Tw6BrHMl42usALvka6meORflnnYwe4=
|
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=
|
github.com/emersion/go-imap-unselect v0.0.0-20161227183655-1e6dc73ac8fe h1:2R2XpJkmbyy7PcSjnCPOnNfu+GuRzgWR9U2+j/d1O+0=
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// 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
|
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;"
|
||||||
|
|
|
@ -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.
|
// Called from go-imap in goroutines - we need to handle panics for each function.
|
||||||
defer im.panicHandler.HandlePanic()
|
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)
|
messageIDs, err := im.apiIDsFromSeqSet(uid, seqSet)
|
||||||
if err != nil || len(messageIDs) == 0 {
|
if err != nil || len(messageIDs) == 0 {
|
||||||
return err
|
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).
|
// messages can be removed from source during labeling (e.g. folder1 -> folder2).
|
||||||
sourceSeqSet := im.storeMailbox.GetUIDList(messageIDs)
|
sourceSeqSet := im.storeMailbox.GetUIDList(messageIDs)
|
||||||
|
|
||||||
targetStoreMBX, err := im.storeAddress.GetMailbox(targetLabel)
|
targetStoreMailbox, err := im.storeAddress.GetMailbox(targetLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// 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.
|
// 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 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
|
// SearchMessages searches messages. The returned list must contain UIDs if
|
||||||
|
|
|
@ -32,6 +32,7 @@ import (
|
||||||
"github.com/emersion/go-imap"
|
"github.com/emersion/go-imap"
|
||||||
imapappendlimit "github.com/emersion/go-imap-appendlimit"
|
imapappendlimit "github.com/emersion/go-imap-appendlimit"
|
||||||
imapidle "github.com/emersion/go-imap-idle"
|
imapidle "github.com/emersion/go-imap-idle"
|
||||||
|
imapmove "github.com/emersion/go-imap-move"
|
||||||
imapquota "github.com/emersion/go-imap-quota"
|
imapquota "github.com/emersion/go-imap-quota"
|
||||||
imapspecialuse "github.com/emersion/go-imap-specialuse"
|
imapspecialuse "github.com/emersion/go-imap-specialuse"
|
||||||
imapunselect "github.com/emersion/go-imap-unselect"
|
imapunselect "github.com/emersion/go-imap-unselect"
|
||||||
|
@ -96,7 +97,7 @@ func NewIMAPServer(debugClient, debugServer bool, port int, tls *tls.Config, ima
|
||||||
|
|
||||||
s.Enable(
|
s.Enable(
|
||||||
imapidle.NewExtension(),
|
imapidle.NewExtension(),
|
||||||
//imapmove.NewExtension(), // extension is not fully implemented: if UIDPLUS exists it MUST return COPYUID and EXPUNGE continuous responses
|
imapmove.NewExtension(),
|
||||||
imapspecialuse.NewExtension(),
|
imapspecialuse.NewExtension(),
|
||||||
imapid.NewExtension(serverID),
|
imapid.NewExtension(serverID),
|
||||||
imapquota.NewExtension(),
|
imapquota.NewExtension(),
|
||||||
|
|
|
@ -9,9 +9,8 @@ Feature: IMAP move messages
|
||||||
And there is IMAP client logged in as "user"
|
And there is IMAP client logged in as "user"
|
||||||
And there is IMAP client selected in "INBOX"
|
And there is IMAP client selected in "INBOX"
|
||||||
|
|
||||||
@ignore
|
|
||||||
Scenario: Move message
|
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"
|
Then IMAP response is "OK"
|
||||||
And mailbox "INBOX" for "user" has messages
|
And mailbox "INBOX" for "user" has messages
|
||||||
| from | to | subject |
|
| from | to | subject |
|
||||||
|
@ -20,7 +19,6 @@ Feature: IMAP move messages
|
||||||
| from | to | subject |
|
| from | to | subject |
|
||||||
| john.doe@mail.com | user@pm.me | foo |
|
| john.doe@mail.com | user@pm.me | foo |
|
||||||
|
|
||||||
@ignore
|
|
||||||
Scenario: Move all messages
|
Scenario: Move all messages
|
||||||
When IMAP client moves messages "1:*" to "Folders/mbox"
|
When IMAP client moves messages "1:*" to "Folders/mbox"
|
||||||
Then IMAP response is "OK"
|
Then IMAP response is "OK"
|
||||||
|
@ -30,20 +28,8 @@ Feature: IMAP move messages
|
||||||
| john.doe@mail.com | user@pm.me | foo |
|
| john.doe@mail.com | user@pm.me | foo |
|
||||||
| jane.doe@mail.com | name@pm.me | bar |
|
| 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
|
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"
|
Then IMAP response is "OK"
|
||||||
And mailbox "All Mail" for "user" has messages
|
And mailbox "All Mail" for "user" has messages
|
||||||
| from | to | subject |
|
| from | to | subject |
|
||||||
|
|
Loading…
Reference in New Issue