diff --git a/internal/bridge/credits.go b/internal/bridge/credits.go
index 9977b19f..5913ab56 100644
--- a/internal/bridge/credits.go
+++ b/internal/bridge/credits.go
@@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see .
-// Code generated by ./credits.sh at Tue Nov 24 08:56:01 AM CET 2020. DO NOT EDIT.
+// Code generated by ./credits.sh at Fri Nov 27 09:08:56 CET 2020. DO NOT EDIT.
package bridge
-const Credits = "github.com/0xAX/notificator;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;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-mbox;github.com/emersion/go-message;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/sentry-go;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/go-resty/resty/v2;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/Masterminds/semver/v3;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;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/gopenpgp/v2;github.com/ProtonMail/go-rfc5322;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/PuerkitoBio/goquery;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;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/Masterminds/semver/v3;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-rfc5322;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;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-mbox;github.com/emersion/go-message;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/sentry-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;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;"
diff --git a/internal/frontend/qml/ImportExportUI/DialogImport.qml b/internal/frontend/qml/ImportExportUI/DialogImport.qml
index bcf0d8b9..6a158336 100644
--- a/internal/frontend/qml/ImportExportUI/DialogImport.qml
+++ b/internal/frontend/qml/ImportExportUI/DialogImport.qml
@@ -355,6 +355,25 @@ Dialog {
InlineLabelSelect {
id: globalLabels
}
+
+ Row {
+ spacing: Style.dialog.spacing
+ CheckBoxLabel {
+ id: importEncrypted
+ text: qsTr("Import encrypted emails as they are")
+ anchors {
+ bottom: parent.bottom
+ bottomMargin: Style.dialog.fontSize/1.8
+ }
+ }
+
+ InfoToolTip {
+ anchors {
+ verticalCenter: importEncrypted.verticalCenter
+ }
+ info: qsTr("When this option is enabled, encrypted emails will be imported as ciphertext. Otherwise, such messages will be skipped.", "todo")
+ }
+ }
}
// Buttons
@@ -1018,7 +1037,7 @@ Dialog {
)
break
case DialogImport.Page.Progress:
- go.startImport(root.address)
+ go.startImport(root.address, importEncrypted.checked)
break
}
}
diff --git a/internal/frontend/qt-ie/import.go b/internal/frontend/qt-ie/import.go
index 2ad3e6e9..0dacc805 100644
--- a/internal/frontend/qt-ie/import.go
+++ b/internal/frontend/qt-ie/import.go
@@ -73,7 +73,7 @@ func (f *FrontendQt) loadStructuresForImport() error {
return nil
}
-func (f *FrontendQt) StartImport(email string) { // TODO email not needed
+func (f *FrontendQt) StartImport(email string, importEncrypted bool) { // TODO email not needed
log.Trace("Starting import")
f.Qml.SetProgressDescription("init") // TODO use const
@@ -84,6 +84,7 @@ func (f *FrontendQt) StartImport(email string) { // TODO email not needed
f.Qml.SetTotal(1)
f.Qml.SetImportLogFileName("")
+ f.transfer.SetSkipEncryptedMessages(!importEncrypted)
progress := f.transfer.Start()
f.Qml.SetImportLogFileName(progress.FileReport())
diff --git a/internal/frontend/qt-ie/ui.go b/internal/frontend/qt-ie/ui.go
index 1040d2ea..563bdb48 100644
--- a/internal/frontend/qt-ie/ui.go
+++ b/internal/frontend/qt-ie/ui.go
@@ -95,7 +95,7 @@ type GoQMLInterface struct {
_ func() string `slot:"leastUsedColor"`
_ func(username string, name string, color string, isLabel bool, sourceID string) bool `slot:"createLabelOrFolder"`
_ func(fpath, address, fileType string, attachEncryptedBody bool) `slot:"startExport"`
- _ func(email string) `slot:"startImport"`
+ _ func(email string, importEncrypted bool) `slot:"startImport"`
_ func() `slot:"resetSource"`
_ func(isFromIMAP bool, sourcePath, sourceEmail, sourcePassword, sourceServe, sourcePort, targetAddress string) `slot:"setupAndLoadForImport"`
diff --git a/internal/importexport/credits.go b/internal/importexport/credits.go
index 2f5febee..9b29292b 100644
--- a/internal/importexport/credits.go
+++ b/internal/importexport/credits.go
@@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see .
-// Code generated by ./credits.sh at Tue Nov 24 08:56:01 AM CET 2020. DO NOT EDIT.
+// Code generated by ./credits.sh at Fri Nov 27 09:08:56 CET 2020. DO NOT EDIT.
package importexport
-const Credits = "github.com/0xAX/notificator;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;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-mbox;github.com/emersion/go-message;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/sentry-go;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/go-resty/resty/v2;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/Masterminds/semver/v3;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;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/gopenpgp/v2;github.com/ProtonMail/go-rfc5322;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/PuerkitoBio/goquery;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;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/Masterminds/semver/v3;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-rfc5322;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;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-mbox;github.com/emersion/go-message;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/sentry-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;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;"
diff --git a/internal/transfer/provider_pmapi_target.go b/internal/transfer/provider_pmapi_target.go
index 9011a4e5..cd542568 100644
--- a/internal/transfer/provider_pmapi_target.go
+++ b/internal/transfer/provider_pmapi_target.go
@@ -124,6 +124,12 @@ func (p *PMAPIProvider) importDraft(msg Message, globalMailbox *Mailbox) (string
return "", errors.Wrap(err, "failed to parse message")
}
+ // Trying to encrypt an encrypted draft will return an error;
+ // users are forbidden to import messages encrypted with foreign keys to drafts.
+ if message.IsEncrypted() {
+ return "", errors.New("refusing to import draft encrypted by foreign key")
+ }
+
p.timeIt.start("encrypt", msg.ID)
err = message.Encrypt(p.keyRing, nil)
p.timeIt.stop("encrypt", msg.ID)
@@ -171,13 +177,12 @@ func (p *PMAPIProvider) importDraft(msg Message, globalMailbox *Mailbox) (string
}
func (p *PMAPIProvider) transferMessage(rules transferRules, progress *Progress, msg Message, preparedImportRequestsCh chan map[string]*pmapi.ImportMsgReq) {
- importMsgReq, err := p.generateImportMsgReq(msg, rules.globalMailbox)
+ importMsgReq, err := p.generateImportMsgReq(rules, progress, msg)
if err != nil {
progress.messageImported(msg.ID, "", err)
return
}
-
- if progress.shouldStop() {
+ if importMsgReq == nil || progress.shouldStop() {
return
}
@@ -191,17 +196,26 @@ func (p *PMAPIProvider) transferMessage(rules transferRules, progress *Progress,
p.nextImportRequestsSize += importMsgReqSize
}
-func (p *PMAPIProvider) generateImportMsgReq(msg Message, globalMailbox *Mailbox) (*pmapi.ImportMsgReq, error) {
+func (p *PMAPIProvider) generateImportMsgReq(rules transferRules, progress *Progress, msg Message) (*pmapi.ImportMsgReq, error) {
message, attachmentReaders, err := p.parseMessage(msg)
if err != nil {
return nil, errors.Wrap(err, "failed to parse message")
}
- p.timeIt.start("encrypt", msg.ID)
- body, err := p.encryptMessage(message, attachmentReaders)
- p.timeIt.stop("encrypt", msg.ID)
- if err != nil {
- return nil, errors.Wrap(err, "failed to encrypt message")
+ var body []byte
+ if message.IsEncrypted() {
+ if rules.skipEncryptedMessages {
+ progress.messageSkipped(msg.ID)
+ return nil, nil
+ }
+ body = msg.Body
+ } else {
+ p.timeIt.start("encrypt", msg.ID)
+ body, err = p.encryptMessage(message, attachmentReaders)
+ p.timeIt.stop("encrypt", msg.ID)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to encrypt message")
+ }
}
unread := 0
@@ -216,8 +230,8 @@ func (p *PMAPIProvider) generateImportMsgReq(msg Message, globalMailbox *Mailbox
labelIDs = append(labelIDs, target.ID)
}
}
- if globalMailbox != nil {
- labelIDs = append(labelIDs, globalMailbox.ID)
+ if rules.globalMailbox != nil {
+ labelIDs = append(labelIDs, rules.globalMailbox.ID)
}
return &pmapi.ImportMsgReq{
diff --git a/internal/transfer/rules.go b/internal/transfer/rules.go
index bfbc572d..26a13487 100644
--- a/internal/transfer/rules.go
+++ b/internal/transfer/rules.go
@@ -49,7 +49,7 @@ type transferRules struct {
globalToTime int64
// skipEncryptedMessages determines whether message which cannot
- // be decrypted should be exported or skipped.
+ // be decrypted should be imported/exported or skipped.
skipEncryptedMessages bool
}
diff --git a/internal/transfer/transfer.go b/internal/transfer/transfer.go
index 1bf6f7ef..ec37a80f 100644
--- a/internal/transfer/transfer.go
+++ b/internal/transfer/transfer.go
@@ -90,7 +90,7 @@ func (t *Transfer) setDefaultRules() error {
}
// SetSkipEncryptedMessages sets whether message which cannot be decrypted
-// should be exported or skipped.
+// should be imported/exported or skipped.
func (t *Transfer) SetSkipEncryptedMessages(skip bool) {
t.rules.setSkipEncryptedMessages(skip)
}
diff --git a/pkg/pmapi/import.go b/pkg/pmapi/import.go
index 6f179c6f..64cc3e4b 100644
--- a/pkg/pmapi/import.go
+++ b/pkg/pmapi/import.go
@@ -67,6 +67,14 @@ func (req *ImportReq) WriteTo(w *multipart.Writer) (err error) {
if _, err = fw.Write(msg.Body); err != nil {
return
}
+
+ // Adding new line to properly fetch the whole body on the API side.
+ // The reason is the bug in PHP: https://bugs.php.net/bug.php?id=75923
+ // Messages generated by PM already have it but importing already
+ // encrypted messages might not have it.
+ if _, err = fw.Write([]byte("\r\n")); err != nil {
+ return
+ }
}
return err
diff --git a/pkg/pmapi/import_test.go b/pkg/pmapi/import_test.go
index 38d8fe91..d6b2e9b5 100644
--- a/pkg/pmapi/import_test.go
+++ b/pkg/pmapi/import_test.go
@@ -127,7 +127,7 @@ func TestClient_Import(t *testing.T) { // nolint[funlen]
t.Error("Expected no error while reading second part body, got:", err)
}
- if string(b) != string(testImportReqs[0].Body) {
+ if string(b) != string(testImportReqs[0].Body)+"\r\n" {
t.Errorf("Invalid message body: expected %v but got %v", string(testImportReqs[0].Body), string(b))
}
diff --git a/pkg/pmapi/messages.go b/pkg/pmapi/messages.go
index 32ee60d2..b6114a02 100644
--- a/pkg/pmapi/messages.go
+++ b/pkg/pmapi/messages.go
@@ -253,6 +253,10 @@ func (m *Message) HasLabelID(labelID string) bool {
return false
}
+func (m *Message) IsEncrypted() bool {
+ return strings.HasPrefix(m.Header.Get("Content-Type"), "multipart/encrypted") || m.IsBodyEncrypted()
+}
+
func (m *Message) IsBodyEncrypted() bool {
trimmedBody := strings.TrimSpace(m.Body)
return strings.HasPrefix(trimmedBody, MessageHeader) &&
diff --git a/test/context/context.go b/test/context/context.go
index 7dcc6d7b..59f76737 100644
--- a/test/context/context.go
+++ b/test/context/context.go
@@ -68,10 +68,11 @@ type TestContext struct {
smtpLastResponses map[string]*mocks.SMTPResponse
// Transfer related variables.
- transferLocalRootForImport string
- transferLocalRootForExport string
- transferRemoteIMAPServer *mocks.IMAPServer
- transferProgress *transfer.Progress
+ transferLocalRootForImport string
+ transferLocalRootForExport string
+ transferRemoteIMAPServer *mocks.IMAPServer
+ transferProgress *transfer.Progress
+ transferSkipEncryptedMessages bool
// Store releated variables.
bddMessageIDsToAPIIDs map[string]string
diff --git a/test/context/transfer.go b/test/context/transfer.go
index a2e792ae..259acada 100644
--- a/test/context/transfer.go
+++ b/test/context/transfer.go
@@ -37,6 +37,16 @@ func (ctx *TestContext) GetTransferProgress() *transfer.Progress {
return ctx.transferProgress
}
+// SetTransferSkipEncryptedMessages sets whether encrypted messages will be skipped.
+func (ctx *TestContext) SetTransferSkipEncryptedMessages(value bool) {
+ ctx.transferSkipEncryptedMessages = value
+}
+
+// GetTransferSkipEncryptedMessages gets whether encrypted messages will be skipped.
+func (ctx *TestContext) GetTransferSkipEncryptedMessages() bool {
+ return ctx.transferSkipEncryptedMessages
+}
+
// GetTransferLocalRootForImport creates temporary root for importing
// if it not exists yet, and returns its path.
func (ctx *TestContext) GetTransferLocalRootForImport() string {
diff --git a/test/features/ie/transfer/import_encrypted.feature b/test/features/ie/transfer/import_encrypted.feature
new file mode 100644
index 00000000..8969ca0f
--- /dev/null
+++ b/test/features/ie/transfer/import_encrypted.feature
@@ -0,0 +1,183 @@
+Feature: Import from EML files
+ Background:
+ Given there is connected user "user"
+ And there is EML file "Inbox/clear.eml"
+ """
+ Subject: clear
+ From: Bridge Test
+ To: Internal Bridge
+
+ secret
+ """
+ And there is EML file "Inbox/encrypted.eml"
+ """
+ Subject: encrypted
+ From: Bridge Test
+ To: Internal Bridge
+
+ -----BEGIN PGP MESSAGE-----
+
+ hQEMA7hGUUsYs0fEAQgA10NwJSNTLm3vpxVtoYBaA9AjFI5H4hKuV3/f2NHbWb2s
+ k5enK3tEIOYdFdrO+NLrV6weHq3Dgu4er3URTQ62tFwjSJyeXxmY0d9J+JdxibJg
+ wqZubuSHYzQHpFqJgoUUWEVEsv0Ao8yQo8BE9iybCKoZf6KojROUuE748oxlxJnV
+ m1XuaVIzgw4xN0GUA5sLLuWeL94b2dZe5SDDQE5POzDgueZ7faefX8U1pGErCRJ0
+ sO6FSw3SF4NpvrxVESWgCmsG5pcuxE2JqB0UoHnNDcqsW8w1Q+GabAPo6UqHhgIg
+ 56MRCWeou2djHIIj9TMUIVFzSG/HvTYQWVS+i4Z7AdJJAXr53GgbZQznO80Qxwcb
+ FFdlwOXHuaXqhqCb338jlQWnbcnUsuJWxBAxkHrlP/nluFqPdIBOglC38kdYSBed
+ 3YwuEB9sXV/fcw==
+ =B05V
+ -----END PGP MESSAGE-----
+ """
+ And there is EML file "Inbox/encrypted-mime.eml"
+ """
+ Subject: encrypted mime
+ From: Bridge Test
+ To: Internal Bridge
+ MIME-Version: 1.0
+ Content-Type: multipart/encrypted; protocol="application/pgp-encrypted"; boundary="WLjzd46aUAiOcuNXjWTJItBZonI56MuAk"
+
+ --WLjzd46aUAiOcuNXjWTJItBZonI56MuAk
+ Content-Type: application/pgp-encrypted
+ Content-Description: PGP/MIME version identification
+
+
+ --WLjzd46aUAiOcuNXjWTJItBZonI56MuAk
+ Content-Type: application/octet-stream; name="encrypted.asc"
+ Content-Description: OpenPGP encrypted message
+ Content-Disposition: inline; filename="encrypted.asc"
+
+ -----BEGIN PGP MESSAGE-----
+
+ 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
+ =4M3l
+ -----END PGP MESSAGE-----
+
+ --WLjzd46aUAiOcuNXjWTJItBZonI56MuAk--
+ """
+ And there is EML file "Inbox/signed.eml"
+ """
+ Subject: signed
+ From: Bridge Test
+ To: Internal Bridge
+
+ -----BEGIN PGP SIGNED MESSAGE-----
+ Hash: SHA256
+
+ secret
+ -----BEGIN PGP SIGNATURE-----
+
+ iQEzBAEBCAAdFiEENaE2ZPemenI4pZah/SJcGo7SJWIFAl+cCAgACgkQ/SJcGo7S
+ JWKsOQf/YakNXkMNjZIu8Hf1WflxtiDXVzTugOicC05k5W64oIqSHt0xNaFKE37k
+ //3eDMWbHvqHKFVdg7qcLsVPeVBaW3bdZUiexGM24OiGgyEitufnHQLOtEDTound
+ JyH5nUeHpvpBKIIOJZNBDM0HsRYnwKwrOWk3N2VRwog4J8J3cmJ/f9bPWNI/0OPT
+ qmtVGRVg6Ge83nZn51Vof//jFzkO4wGYCsE0aF0Ywc7nISZuyKQzmu/qgmwzDG50
+ PjpvIQ/ygisRPNdRlylXEqyoIDCQ+v0AnxhhwX/5dbt6xMuMMOxBrFSC94Zce1Vj
+ x2ssXlT4ONPnkI/YWwhtQPLU628IMg==
+ =GiS3
+ -----END PGP SIGNATURE-----
+ """
+ And there is EML file "Inbox/encrypted-signed.eml"
+ """
+ Subject: encrypted and signed
+ From: Bridge Test
+ To: Internal Bridge
+
+ -----BEGIN PGP MESSAGE-----
+
+ hQEMA7hGUUsYs0fEAQf/dppHciWIf+o4l0gEfHeyHV/HVhG4es0aVQYrwFQlSWVx
+ estMuyLBSMfrsQXLago7Q9ZNo/XnKszzprCXxxYH52hAg64oAsjKB3jgRmVizs8b
+ 8lj0BRf003wUluS/0msV9SiEZBGeL8jGq6Te9vaM8OHHhIVzVjGnRdTSC0jBE6cS
+ vy8IBHXYe0LfdZiPojPDPGQdSej+H3uu7eZGBvVHTDeQLPDel4k7Ykdr0qlNXs6O
+ 5XpM5YG4w+t0aG+YROPH+BUj8PpPojQ/lrv/yFISTRbHlEd8N50w8BNTnBet+9Vm
+ oPcyvN+RQxBlvRuPpDjUmREvmtObKZV6+m6gocemx9LAzQEeVLcpjO/hJhl8gX72
+ MNz3McU7aXf5sSoOPdHDNx8T2NON/2bwG5FE+PRMuVywTKhCB7o8VAsJpGMQ8xRM
+ 5WCNhow0AI7kni8yZA+GbvspnJWfit9tCTR5MIFHCSH9J3kJJnWkxQSN04GGpBcd
+ n43GWn7O7ufA4lMMZiGXMdi/J1iV9waAsIfMPk29BMq6xK0/jJYdHqQS+vNsSnF5
+ xL/Ir4RYq4SFFA06A/E7HpXr2ruZhBQCkzaIIdrVJR/Lp2VLJIVulTBQK8y2AFtj
+ JeeKS0kIuC/7UPF2O624kwNr8dmIhDJYusFs6ZeED/nAKwDO/vP2CSwVC3sUjn3N
+ u+sWqQUTxSmjhRVf9b0+VyTh0mXCovJQXomL6Zz6lxXuJqqzELIOfCxYD1z9GwTG
+ cT08Aa2eEpf3agdLCTxvjO3iq9FksMHvIN+LSCQ6Pw+aTByjrk0oMmvGbANAogTk
+ yrplG/iRVlmq0p/Cfl5UEjKqT/nt5j9zbpeuYXmhjiBT9SBE07oUVLY1VT7ihcY=
+ =qYnL
+ -----END PGP MESSAGE-----
+ """
+
+ Scenario: Import encrypted
+ Given there is skip encrypted messages set to "false"
+ When user "user" imports local files
+ Then progress result is "OK"
+ And transfer failed for 0 messages
+ And transfer exported 5 messages
+ And transfer imported 5 messages
+ And transfer skipped 0 messages
+ And API mailbox "INBOX" for "user" has messages
+ | from | to | subject |
+ | bridgetest@pm.test | test@protonmail.com | clear |
+ | bridgetest@pm.test | test@protonmail.com | encrypted |
+ | bridgetest@pm.test | test@protonmail.com | encrypted mime |
+ | bridgetest@pm.test | test@protonmail.com | signed |
+ | bridgetest@pm.test | test@protonmail.com | encrypted and signed |
+
+ Scenario: Skip encrypted
+ Given there is skip encrypted messages set to "true"
+ When user "user" imports local files
+ Then progress result is "OK"
+ And transfer failed for 0 messages
+ And transfer exported 5 messages
+ And transfer imported 2 messages
+ And transfer skipped 3 messages
+ And API mailbox "INBOX" for "user" has messages
+ | from | to | subject |
+ | bridgetest@pm.test | test@protonmail.com | clear |
+ | bridgetest@pm.test | test@protonmail.com | signed |
diff --git a/test/transfer_actions_test.go b/test/transfer_actions_test.go
index ae049c2e..f5b86b7a 100644
--- a/test/transfer_actions_test.go
+++ b/test/transfer_actions_test.go
@@ -143,6 +143,7 @@ func doTransfer(bddUserID, bddAddressID string, rules *gherkin.DataTable, getTra
if err := setRules(transferrer, rules); err != nil {
return internalError(err, "failed to set rules")
}
+ transferrer.SetSkipEncryptedMessages(ctx.GetTransferSkipEncryptedMessages())
progress := transferrer.Start()
ctx.SetTransferProgress(progress)
return nil
diff --git a/test/transfer_checks_test.go b/test/transfer_checks_test.go
index 1ab5ac15..e1ea01fa 100644
--- a/test/transfer_checks_test.go
+++ b/test/transfer_checks_test.go
@@ -40,6 +40,7 @@ func TransferChecksFeatureContext(s *godog.Suite) {
s.Step(`^progress result is "([^"]*)"$`, progressFinishedWith)
s.Step(`^transfer exported (\d+) messages$`, transferExportedNumberOfMessages)
s.Step(`^transfer imported (\d+) messages$`, transferImportedNumberOfMessages)
+ s.Step(`^transfer skipped (\d+) messages$`, transferSkippedNumberOfMessages)
s.Step(`^transfer failed for (\d+) messages$`, transferFailedForNumberOfMessages)
s.Step(`^transfer exported messages$`, transferExportedMessages)
s.Step(`^exported messages match the original ones$`, exportedMessagesMatchTheOriginalOnes)
@@ -77,6 +78,13 @@ func transferImportedNumberOfMessages(wantCount int) error {
return ctx.GetTestingError()
}
+func transferSkippedNumberOfMessages(wantCount int) error {
+ progress := ctx.GetTransferProgress()
+ counts := progress.GetCounts()
+ a.Equal(ctx.GetTestingT(), uint(wantCount), counts.Skipped)
+ return ctx.GetTestingError()
+}
+
func transferFailedForNumberOfMessages(wantCount int) error {
progress := ctx.GetTransferProgress()
failedMessages := progress.GetFailedMessages()
diff --git a/test/transfer_setup_test.go b/test/transfer_setup_test.go
index b52bec46..68ad076e 100644
--- a/test/transfer_setup_test.go
+++ b/test/transfer_setup_test.go
@@ -41,6 +41,7 @@ func TransferSetupFeatureContext(s *godog.Suite) {
s.Step(`^there are IMAP mailboxes$`, thereAreIMAPMailboxes)
s.Step(`^there are IMAP messages$`, thereAreIMAPMessages)
s.Step(`^there is IMAP message in mailbox "([^"]*)" with seq (\d+), uid (\d+), time "([^"]*)" and subject "([^"]*)"$`, thereIsIMAPMessage)
+ s.Step(`^there is skip encrypted messages set to "([^"]*)"$`, thereIsSkipEncryptedMessagesSetTo)
}
func thereAreEMLFiles(messages *gherkin.DataTable) error {
@@ -259,3 +260,15 @@ func createFile(fileName, body string) error {
_, err = f.WriteString(body)
return internalError(err, "failed to write to file")
}
+
+func thereIsSkipEncryptedMessagesSetTo(value string) error {
+ switch value {
+ case "true":
+ ctx.SetTransferSkipEncryptedMessages(true)
+ case "false":
+ ctx.SetTransferSkipEncryptedMessages(false)
+ default:
+ return fmt.Errorf("expected either true or false, was %v", value)
+ }
+ return nil
+}
diff --git a/unreleased.md b/unreleased.md
index 0fb9ce82..cacff4f6 100644
--- a/unreleased.md
+++ b/unreleased.md
@@ -9,3 +9,5 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
### Changed
### Removed
+* GODT-651 Build creates proper binary names.
+* GODT-148 Allow import (using the Import-Export app) of already encrypted messages as is.