From 835bf1e77fa67168aa1347867d5add20dcc031c9 Mon Sep 17 00:00:00 2001 From: James Houlahan Date: Wed, 9 Jun 2021 09:51:31 +0200 Subject: [PATCH 1/8] Other: make changelog linter happy --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index ff95d49f..49143f7e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,7 +14,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) ### Added * GODT-1155: Update gopenpgp v2.1.9 and use go-srp. * GODT-1044: Lite parser for appended messages. -* GODT-1183: Add test for getting contact emails by email +* GODT-1183: Add test for getting contact emails by email. * GODT-1184: Preserve signatures in externally signed messages. ### Changed From 6d784f2444daacd6088eb6f24bef2316a5c939f6 Mon Sep 17 00:00:00 2001 From: Andrzej Szafranski Date: Thu, 27 May 2021 12:44:27 +0000 Subject: [PATCH 2/8] Other: release notes 1.8.5 --- release-notes/bridge_early.md | 24 ++++++++++++++++++------ release-notes/bridge_stable.md | 8 ++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/release-notes/bridge_early.md b/release-notes/bridge_early.md index 0d44e25a..47aaf860 100644 --- a/release-notes/bridge_early.md +++ b/release-notes/bridge_early.md @@ -1,15 +1,27 @@ -## v1.8.3 -- 2021-05-31 +## v1.8.5 +- 2021-06-11 ### New -- Improved moving messages from other accounts to ProtonMail - implemented new parser for processing such messages -- Performance improvements +- Implemented golang Secure Remote Password Protocol +- Updated crypto-libraries to gopenpgp/v2 v2.1.9 +- Implemented new message parser (for imports from external accounts) ### Fixed -- Sync issue with Microsoft Outlook (changed the order of processing requests) -- Fetching the bodies of non-multipart messages +- Bridge not to strip PGP signatures of incoming clear text messages +- Import of messages with malformed MIME header +- Improved parsing of message headers +- Fetching bodies of non-multipart messages +- Sync and performance improvements + + +## v1.8.3 +- 2021-05-27 + +### Fixed + +- A bug with sending encrypted emails to external contacts ## v1.8.2 diff --git a/release-notes/bridge_stable.md b/release-notes/bridge_stable.md index e2328c9b..e2328088 100644 --- a/release-notes/bridge_stable.md +++ b/release-notes/bridge_stable.md @@ -1,3 +1,11 @@ +## v1.8.3 +- 2021-05-27 + +### Fixed + +- A bug with sending encrypted emails to external contacts + + ## v1.8.2 - 2021-05-21 From 5bf359d34f0784a29eb190688afd6e194e100f26 Mon Sep 17 00:00:00 2001 From: James Houlahan Date: Wed, 9 Jun 2021 09:27:34 +0200 Subject: [PATCH 3/8] GODT-1193: don't use message.Read; permit non-UTF-8 charsets --- go.mod | 1 + go.sum | 9 ++----- pkg/message/build_framework_test.go | 20 +++++++++++++++ pkg/message/build_rfc822.go | 19 +++----------- pkg/message/build_test.go | 25 +++++++++++++++++++ .../pgp-mime-body-plaintext-latin2.eml | 8 ++++++ 6 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 pkg/message/testdata/pgp-mime-body-plaintext-latin2.eml diff --git a/go.mod b/go.mod index fd0fb525..ae541d3b 100644 --- a/go.mod +++ b/go.mod @@ -71,5 +71,6 @@ require ( replace ( github.com/docker/docker-credential-helpers => github.com/ProtonMail/docker-credential-helpers v1.1.0 github.com/emersion/go-imap => github.com/ProtonMail/go-imap v0.0.0-20201228133358-4db68cea0cac + github.com/emersion/go-message => github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753 github.com/jameskeane/bcrypt => github.com/ProtonMail/bcrypt v0.0.0-20210511135022-227b4adcab57 ) diff --git a/go.sum b/go.sum index 02ee7bff..2f79a1c2 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/ProtonMail/go-imap v0.0.0-20201228133358-4db68cea0cac h1:2xU3QncAiS/W github.com/ProtonMail/go-imap v0.0.0-20201228133358-4db68cea0cac/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU= github.com/ProtonMail/go-imap-id v0.0.0-20190926060100-f94a56b9ecde h1:5koQozTDELymYOyFbQ/VSubexAEXzDR8qGM5mO8GRdw= github.com/ProtonMail/go-imap-id v0.0.0-20190926060100-f94a56b9ecde/go.mod h1:795VPXcRUIQ9JyMNHP4el582VokQfippgjkQP3Gk0r0= +github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753 h1:I8IsYA297x0QLU80G5I6aLYUu3JYNSpo8j5fkXtFDW0= +github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4= github.com/ProtonMail/go-mime v0.0.0-20190923161245-9b5a4261663a h1:W6RrgN/sTxg1msqzFFb+G80MFmpjMw61IU+slm+wln4= github.com/ProtonMail/go-mime v0.0.0-20190923161245-9b5a4261663a/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4= github.com/ProtonMail/go-rfc5322 v0.8.0 h1:7emrf75n3CDIduQflx7aT1nJa5h/kGsiFKUYX/+IAkU= @@ -81,15 +83,11 @@ github.com/emersion/go-imap-unselect v0.0.0-20171113212723-b985794e5f26 h1:FiSb8 github.com/emersion/go-imap-unselect v0.0.0-20171113212723-b985794e5f26/go.mod h1:+gnnZx3Mg3MnCzZrv0eZdp5puxXQUgGT/6N6L7ShKfM= github.com/emersion/go-mbox v1.0.2 h1:tE/rT+lEugK9y0myEymCCHnwlZN04hlXPrbKkxRBA5I= github.com/emersion/go-mbox v1.0.2/go.mod h1:Yp9IVuuOYLEuMv4yjgDHvhb5mHOcYH6x92Oas3QqEZI= -github.com/emersion/go-message v0.11.1/go.mod h1:C4jnca5HOTo4bGN9YdqNQM9sITuT3Y0K6bSUw9RklvY= -github.com/emersion/go-message v0.12.1-0.20201221184100-40c3f864532b h1:xYuhW6egTaCP+zjbUcfoy/Dr3ASdVPR9W7fmkHvZHPE= -github.com/emersion/go-message v0.12.1-0.20201221184100-40c3f864532b/go.mod h1:N1JWdZQ2WRUalmdHAX308CWBq747VJ8oUorFI3VCBwU= github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/emersion/go-smtp v0.14.0 h1:RYW203p+EcPjL8Z/ZpT9lZ6iOc8MG1MQzEx1UKEkXlA= github.com/emersion/go-smtp v0.14.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= -github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 h1:IbFBtwoTQyw0fIM5xv1HF+Y+3ZijDR839WMulgxCcUY= github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= github.com/emersion/go-vcard v0.0.0-20190105225839-8856043f13c5 h1:n9qx98xiS5V4x2WIpPC2rr9mUM5ri9r/YhCEKbhCHro= @@ -176,9 +174,6 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8= -github.com/martinlindhe/base36 v1.1.0 h1:cIwvvwYse/0+1CkUPYH5ZvVIYG3JrILmQEIbLuar02Y= -github.com/martinlindhe/base36 v1.1.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= diff --git a/pkg/message/build_framework_test.go b/pkg/message/build_framework_test.go index 4e00ce00..16ddfed6 100644 --- a/pkg/message/build_framework_test.go +++ b/pkg/message/build_framework_test.go @@ -33,6 +33,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/text/encoding/htmlindex" ) func newTestFetcher( @@ -298,6 +299,25 @@ func decryptsTo(kr *crypto.KeyRing, want string) decryptsToMatcher { return decryptsToMatcher{kr: kr, want: want} } +type decodesToMatcher struct { + charset string + want string +} + +func (matcher decodesToMatcher) match(t *testing.T, have string) { + enc, err := htmlindex.Get(matcher.charset) + require.NoError(t, err) + + dec, err := enc.NewDecoder().String(have) + require.NoError(t, err) + + assert.Equal(t, matcher.want, dec) +} + +func decodesTo(charset string, want string) decodesToMatcher { + return decodesToMatcher{charset: charset, want: want} +} + type verifiesAgainstMatcher struct { kr *crypto.KeyRing sig *crypto.PGPSignature diff --git a/pkg/message/build_rfc822.go b/pkg/message/build_rfc822.go index 36366ca9..50471a3b 100644 --- a/pkg/message/build_rfc822.go +++ b/pkg/message/build_rfc822.go @@ -20,7 +20,6 @@ package message import ( "bytes" "encoding/base64" - "io/ioutil" "mime" "net/mail" "strings" @@ -290,17 +289,12 @@ func writeMultipartSignedRFC822(header message.Header, body []byte, sig pmapi.Si return nil, err } - ent, err := message.Read(bytes.NewReader(body)) + bodyHeader, bodyData, err := readHeaderBody(body) if err != nil { return nil, err } - bodyPart, err := w.CreatePart(ent.Header) - if err != nil { - return nil, err - } - - bodyData, err := ioutil.ReadAll(ent.Body) + bodyPart, err := w.CreatePart(message.Header{Header: *bodyHeader}) if err != nil { return nil, err } @@ -347,12 +341,12 @@ func writeMultipartSignedRFC822(header message.Header, body []byte, sig pmapi.Si func writeMultipartEncryptedRFC822(header message.Header, body []byte) ([]byte, error) { buf := new(bytes.Buffer) - ent, err := message.Read(bytes.NewReader(body)) + bodyHeader, bodyData, err := readHeaderBody(body) if err != nil { return nil, err } - entFields := ent.Header.Fields() + entFields := bodyHeader.Fields() for entFields.Next() { header.Set(entFields.Key(), entFields.Value()) @@ -363,11 +357,6 @@ func writeMultipartEncryptedRFC822(header message.Header, body []byte) ([]byte, return nil, err } - bodyData, err := ioutil.ReadAll(ent.Body) - if err != nil { - return nil, err - } - if _, err := w.Write(bodyData); err != nil { return nil, err } diff --git a/pkg/message/build_test.go b/pkg/message/build_test.go index c9f7fe70..f692a33c 100644 --- a/pkg/message/build_test.go +++ b/pkg/message/build_test.go @@ -98,6 +98,31 @@ func TestBuildPlainEncryptedMessage(t *testing.T) { expectBody(contains(`Where do fruits go on vacation? Pear-is!`)) } +func TestBuildPlainEncryptedLatin2Message(t *testing.T) { + m := gomock.NewController(t) + defer m.Finish() + + b := NewBuilder(1, 1, 1) + defer b.Done() + + body := readerToString(getFileReader("pgp-mime-body-plaintext-latin2.eml")) + + kr := tests.MakeKeyRing(t) + msg := newTestMessage(t, kr, "messageID", "addressID", "multipart/mixed", body, time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC)) + + res, err := b.NewJob(context.Background(), newTestFetcher(m, kr, msg), msg.ID).GetResult() + require.NoError(t, err) + + section(t, res). + expectContentType(is(`text/plain`)). + expectContentTypeParam("charset", is(`iso-8859-2`)). + expectDate(is(`Wed, 01 Jan 2020 00:00:00 +0000`)). + expectHeader(`Subject`, is(`plain no pubkey no sign`)). + expectHeader(`From`, is(`"pm.bridge.qa" `)). + expectHeader(`To`, is(`schizofrenic@pm.me`)). + expectBody(decodesTo("iso-8859-2", "řšřšřš\r\n")) +} + func TestBuildHTMLEncryptedMessage(t *testing.T) { m := gomock.NewController(t) defer m.Finish() diff --git a/pkg/message/testdata/pgp-mime-body-plaintext-latin2.eml b/pkg/message/testdata/pgp-mime-body-plaintext-latin2.eml new file mode 100644 index 00000000..d971a446 --- /dev/null +++ b/pkg/message/testdata/pgp-mime-body-plaintext-latin2.eml @@ -0,0 +1,8 @@ +Subject: plain no pubkey no sign +From: "pm.bridge.qa" +To: schizofrenic@pm.me +Message-ID: <564b9c7c-91eb-6508-107a-35108f383a44@gmail.com> +Content-Type: text/plain; charset=iso-8859-2; format=flowed +Content-Language: en-US + +ø¹ø¹ø¹ From 0c6a098af9ea331214af717e2a15c542ff8f5c6e Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 19 May 2021 09:57:36 +0200 Subject: [PATCH 4/8] GODT-1166: Reduce the number of auth for live test - Changed: Do not reauth controller clients. - Changed: Verbosisty is set only once before run - Changed: AddUser takes TestAccount as argument - Added: Setup/clean up before/after test run - Added: Access to the current refresh token from pmapi.Client interface. - Added: Context function to add test a user to bridge without login, just call users.FinishLogin. - Added: PMAPIController.GetAuthClient returns authenticated client for username. - Added: Persistent clients does not loggout after every scenario. - Changed: Disabled no-internet tests. --- pkg/pmapi/auth.go | 10 ++ pkg/pmapi/client_types.go | 2 + pkg/pmapi/mocks/mocks.go | 14 +++ test/Makefile | 2 +- test/bdd_test.go | 3 + test/benchmarks/bench_test.go | 2 +- test/context/context.go | 2 - test/context/globals.go | 40 +++++++ test/context/pmapi_controller.go | 4 +- test/context/users.go | 13 ++ test/fakeapi/auth.go | 10 ++ test/fakeapi/controller.go | 2 + test/fakeapi/controller_control.go | 28 ++++- test/fakeapi/controller_session.go | 11 +- test/features/bridge/imap/auth.feature | 6 +- test/features/bridge/no_internet.feature | 10 +- test/features/bridge/start.feature | 8 +- test/features/bridge/users/delete.feature | 6 +- test/features/bridge/users/relogin.feature | 4 +- test/liveapi/controller.go | 23 ++-- test/liveapi/labels.go | 12 +- test/liveapi/messages.go | 13 +- test/liveapi/persistent_clients.go | 131 +++++++++++++++++++++ test/liveapi/users.go | 43 ++++--- test/users_setup_test.go | 21 +++- 25 files changed, 334 insertions(+), 86 deletions(-) create mode 100644 test/context/globals.go create mode 100644 test/liveapi/persistent_clients.go diff --git a/pkg/pmapi/auth.go b/pkg/pmapi/auth.go index 8773278d..d58b1060 100644 --- a/pkg/pmapi/auth.go +++ b/pkg/pmapi/auth.go @@ -217,3 +217,13 @@ func randomString(length int) string { return base64.StdEncoding.EncodeToString(noise)[:length] } + +func (c *client) GetCurrentAuth() *Auth { + return &Auth{ + UserID: c.user.ID, + AuthRefresh: AuthRefresh{ + UID: c.uid, + RefreshToken: c.ref, + }, + } +} diff --git a/pkg/pmapi/client_types.go b/pkg/pmapi/client_types.go index bf87bd60..73f072e1 100644 --- a/pkg/pmapi/client_types.go +++ b/pkg/pmapi/client_types.go @@ -73,6 +73,8 @@ type Client interface { KeyRingForAddressID(string) (kr *crypto.KeyRing, err error) GetPublicKeysForEmail(context.Context, string) ([]PublicKey, bool, error) + + GetCurrentAuth() *Auth } type AuthRefreshHandler func(*AuthRefresh) diff --git a/pkg/pmapi/mocks/mocks.go b/pkg/pmapi/mocks/mocks.go index 78492681..1f46f6c8 100644 --- a/pkg/pmapi/mocks/mocks.go +++ b/pkg/pmapi/mocks/mocks.go @@ -301,6 +301,20 @@ func (mr *MockClientMockRecorder) GetContactEmailByEmail(arg0, arg1, arg2, arg3 return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContactEmailByEmail", reflect.TypeOf((*MockClient)(nil).GetContactEmailByEmail), arg0, arg1, arg2, arg3) } +// GetCurrentAuth mocks base method +func (m *MockClient) GetCurrentAuth() *pmapi.Auth { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentAuth") + ret0, _ := ret[0].(*pmapi.Auth) + return ret0 +} + +// GetCurrentAuth indicates an expected call of GetCurrentAuth +func (mr *MockClientMockRecorder) GetCurrentAuth() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentAuth", reflect.TypeOf((*MockClient)(nil).GetCurrentAuth)) +} + // GetEvent mocks base method func (m *MockClient) GetEvent(arg0 context.Context, arg1 string) (*pmapi.Event, error) { m.ctrl.T.Helper() diff --git a/test/Makefile b/test/Makefile index 36197e27..ff21c606 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ .PHONY: check-go check-godog install-godog test test-bridge test-ie test-live test-live-bridge test-live-ie test-stage test-debug test-live-debug bench export GO111MODULE=on -export BRIDGE_VERSION:=1.5.5+integrationtests +export BRIDGE_VERSION:=1.8.2+integrationtests export VERBOSITY?=fatal export TEST_DATA=testdata export TEST_APP?=bridge diff --git a/test/bdd_test.go b/test/bdd_test.go index 0817b587..0b06c025 100644 --- a/test/bdd_test.go +++ b/test/bdd_test.go @@ -29,6 +29,9 @@ const ( ) func FeatureContext(s *godog.Suite) { + s.BeforeSuite(context.BeforeRun) + s.AfterSuite(context.AfterRun) + s.BeforeScenario(beforeScenario) s.AfterScenario(afterScenario) diff --git a/test/benchmarks/bench_test.go b/test/benchmarks/bench_test.go index 4e01b6df..c7212914 100644 --- a/test/benchmarks/bench_test.go +++ b/test/benchmarks/bench_test.go @@ -35,7 +35,7 @@ func benchTestContext() (*context.TestContext, *mocks.IMAPClient) { panic("account " + username + " does not exist") } - _ = ctx.GetPMAPIController().AddUser(account.User(), account.Addresses(), account.Password(), account.IsTwoFAEnabled()) + _ = ctx.GetPMAPIController().AddUser(account) if err := ctx.LoginUser(account.Username(), account.Password(), account.MailboxPassword()); err != nil { panic(err) } diff --git a/test/context/context.go b/test/context/context.go index 4d2a1dc0..0778bebf 100644 --- a/test/context/context.go +++ b/test/context/context.go @@ -94,8 +94,6 @@ type TestContext struct { // New returns a new test TestContext. func New(app string) *TestContext { - setLogrusVerbosityFromEnv() - listener := listener.New() pmapiController, clientManager := newPMAPIController(app, listener) diff --git a/test/context/globals.go b/test/context/globals.go new file mode 100644 index 00000000..619cc5f5 --- /dev/null +++ b/test/context/globals.go @@ -0,0 +1,40 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge.Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package context + +import ( + "os" + + "github.com/ProtonMail/proton-bridge/test/liveapi" +) + +// BeforeRun does necessary setup. +func BeforeRun() { + setLogrusVerbosityFromEnv() + + if os.Getenv(EnvName) == EnvLive { + liveapi.SetupPersistentClients() + } +} + +// AfterRun does necessary cleanup. +func AfterRun() { + if os.Getenv(EnvName) == EnvLive { + liveapi.CleanupPersistentClients() + } +} diff --git a/test/context/pmapi_controller.go b/test/context/pmapi_controller.go index 17c5a1b9..7de8799d 100644 --- a/test/context/pmapi_controller.go +++ b/test/context/pmapi_controller.go @@ -23,6 +23,7 @@ import ( "github.com/ProtonMail/proton-bridge/internal/events" "github.com/ProtonMail/proton-bridge/pkg/listener" "github.com/ProtonMail/proton-bridge/pkg/pmapi" + "github.com/ProtonMail/proton-bridge/test/accounts" "github.com/ProtonMail/proton-bridge/test/fakeapi" "github.com/ProtonMail/proton-bridge/test/liveapi" ) @@ -30,7 +31,8 @@ import ( type PMAPIController interface { TurnInternetConnectionOff() TurnInternetConnectionOn() - AddUser(user *pmapi.User, addresses *pmapi.AddressList, password []byte, twoFAEnabled bool) error + GetAuthClient(username string) pmapi.Client + AddUser(account *accounts.TestAccount) error AddUserLabel(username string, label *pmapi.Label) error GetLabelIDs(username string, labelNames []string) ([]string, error) AddUserMessage(username string, message *pmapi.Message) (string, error) diff --git a/test/context/users.go b/test/context/users.go index 9fa66ec0..cea3601e 100644 --- a/test/context/users.go +++ b/test/context/users.go @@ -27,6 +27,7 @@ import ( "github.com/ProtonMail/go-srp" "github.com/ProtonMail/proton-bridge/internal/store" "github.com/ProtonMail/proton-bridge/internal/users" + "github.com/ProtonMail/proton-bridge/pkg/pmapi" "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) @@ -61,6 +62,18 @@ func (ctx *TestContext) LoginUser(username string, password, mailboxPassword []b return nil } +// FinishLogin prevents authentication if not necessary. +func (ctx *TestContext) FinishLogin(client pmapi.Client, mailboxPassword string) error { + user, err := ctx.users.FinishLogin(client, client.GetCurrentAuth(), mailboxPassword) + if err != nil { + return errors.Wrap(err, "failed to finish login") + } + + ctx.addCleanupChecked(user.Logout, "Logging out user") + + return nil +} + // GetUser retrieves the bridge user matching the given query string. func (ctx *TestContext) GetUser(username string) (*users.User, error) { return ctx.users.GetUser(username) diff --git a/test/fakeapi/auth.go b/test/fakeapi/auth.go index 8f45a8df..b63fcc46 100644 --- a/test/fakeapi/auth.go +++ b/test/fakeapi/auth.go @@ -63,3 +63,13 @@ func (api *FakePMAPI) AuthDelete(_ context.Context) error { return nil } + +func (api *FakePMAPI) GetCurrentAuth() *pmapi.Auth { + return &pmapi.Auth{ + UserID: api.userID, + AuthRefresh: pmapi.AuthRefresh{ + UID: api.uid, + RefreshToken: api.ref, + }, + } +} diff --git a/test/fakeapi/controller.go b/test/fakeapi/controller.go index a01f0064..50a5d6d1 100644 --- a/test/fakeapi/controller.go +++ b/test/fakeapi/controller.go @@ -24,6 +24,8 @@ import ( "github.com/sirupsen/logrus" ) +// Controller implements dummy PMAPIController interface without actual +// endpoint. type Controller struct { // Internal states. lock *sync.RWMutex diff --git a/test/fakeapi/controller_control.go b/test/fakeapi/controller_control.go index 35a9e184..8e853b65 100644 --- a/test/fakeapi/controller_control.go +++ b/test/fakeapi/controller_control.go @@ -22,8 +22,10 @@ import ( "errors" "fmt" "strings" + "time" "github.com/ProtonMail/proton-bridge/pkg/pmapi" + "github.com/ProtonMail/proton-bridge/test/accounts" ) var systemLabelNameToID = map[string]string{ //nolint[gochecknoglobals] @@ -61,13 +63,15 @@ func (ctl *Controller) ReorderAddresses(user *pmapi.User, addressIDs []string) e return api.ReorderAddresses(context.Background(), addressIDs) } -func (ctl *Controller) AddUser(user *pmapi.User, addresses *pmapi.AddressList, password []byte, twoFAEnabled bool) error { - ctl.usersByUsername[user.Name] = &fakeUser{ - user: user, - password: password, - has2FA: twoFAEnabled, +func (ctl *Controller) AddUser(account *accounts.TestAccount) error { + ctl.usersByUsername[account.User().Name] = &fakeUser{ + user: account.User(), + password: account.Password(), + has2FA: account.IsTwoFAEnabled(), } - ctl.addressesByUsername[user.Name] = addresses + ctl.addressesByUsername[account.User().Name] = account.Addresses() + ctl.createSession(account.User().Name, true) + return nil } @@ -181,3 +185,15 @@ func (ctl *Controller) GetMessages(username, labelID string) ([]*pmapi.Message, } return messages, nil } + +func (ctl *Controller) GetAuthClient(username string) pmapi.Client { + for uid, session := range ctl.sessionsByUID { + if session.username == username { + return ctl.clientManager.NewClient(uid, session.acc, session.ref, time.Now()) + } + } + + ctl.log.WithField("username", username).Fatal("Cannot get authenticated client.") + + return nil +} diff --git a/test/fakeapi/controller_session.go b/test/fakeapi/controller_session.go index 87de705f..6fd81de5 100644 --- a/test/fakeapi/controller_session.go +++ b/test/fakeapi/controller_session.go @@ -51,24 +51,25 @@ func (ctl *Controller) checkScope(uid string) bool { } func (ctl *Controller) createSessionIfAuthorized(username string, password []byte) (*fakeSession, error) { - // get user user, ok := ctl.usersByUsername[username] if !ok || !bytes.Equal(user.password, password) { return nil, errWrongNameOrPassword } - // create session + return ctl.createSession(username, !user.has2FA), nil +} + +func (ctl *Controller) createSession(username string, hasFullScope bool) *fakeSession { session := &fakeSession{ username: username, uid: ctl.tokenGenerator.next("uid"), acc: ctl.tokenGenerator.next("acc"), ref: ctl.tokenGenerator.next("ref"), - hasFullScope: !user.has2FA, + hasFullScope: hasFullScope, } ctl.sessionsByUID[session.uid] = session - - return session, nil + return session } func (ctl *Controller) refreshSessionIfAuthorized(uid, ref string) (*fakeSession, error) { diff --git a/test/features/bridge/imap/auth.feature b/test/features/bridge/imap/auth.feature index 3191d1e3..a86e0897 100644 --- a/test/features/bridge/imap/auth.feature +++ b/test/features/bridge/imap/auth.feature @@ -15,7 +15,7 @@ Feature: IMAP auth Then IMAP response is "IMAP error: NO account is logged out, use the app to login again" Scenario: Authenticates with connected user that was loaded without internet - Given there is connected user "user" + Given there is user "user" which just logged in And there is no internet connection When bridge starts And the internet connection is restored @@ -28,13 +28,13 @@ Feature: IMAP auth Then "user" is connected Scenario: Authenticates with freshly logged-out user - Given there is connected user "user" + Given there is user "user" which just logged in When "user" logs out And IMAP client authenticates "user" Then IMAP response is "IMAP error: NO account is logged out, use the app to login again" Scenario: Authenticates user which was re-logged in - Given there is connected user "user" + Given there is user "user" which just logged in When "user" logs out And IMAP client authenticates "user" Then IMAP response is "IMAP error: NO account is logged out, use the app to login again" diff --git a/test/features/bridge/no_internet.feature b/test/features/bridge/no_internet.feature index 5abb1841..4025f9a4 100644 --- a/test/features/bridge/no_internet.feature +++ b/test/features/bridge/no_internet.feature @@ -1,15 +1,17 @@ Feature: Servers are closed when no internet + # FIXME: Locally works, has lags on CI. Looks like it breaks other tests as well. + @ignore Scenario: All connection are closed and then restored multiple times Given there is connected user "user" And there is IMAP client "i1" logged in as "user" And there is SMTP client "s1" logged in as "user" When there is no internet connection - And 1 second pass + And 3 seconds pass Then IMAP client "i1" is logged out And SMTP client "s1" is logged out Given the internet connection is restored - And 1 second pass + And 3 seconds pass And there is IMAP client "i2" logged in as "user" And there is SMTP client "s2" logged in as "user" When IMAP client "i2" gets info of "INBOX" @@ -17,11 +19,11 @@ Feature: Servers are closed when no internet Then IMAP response to "i2" is "OK" Then SMTP response to "s2" is "OK" When there is no internet connection - And 1 second pass + And 3 seconds pass Then IMAP client "i2" is logged out And SMTP client "s2" is logged out Given the internet connection is restored - And 1 second pass + And 3 seconds pass And there is IMAP client "i3" logged in as "user" And there is SMTP client "s3" logged in as "user" When IMAP client "i3" gets info of "INBOX" diff --git a/test/features/bridge/start.feature b/test/features/bridge/start.feature index 2d0b82e7..2b7c50c0 100644 --- a/test/features/bridge/start.feature +++ b/test/features/bridge/start.feature @@ -1,6 +1,6 @@ Feature: Start bridge Scenario: Start with connected user, database file and internet connection - Given there is connected user "user" + Given there is user "user" which just logged in And there is database file for "user" When bridge starts Then "user" is connected @@ -8,7 +8,7 @@ Feature: Start bridge And "user" has running event loop Scenario: Start with connected user, database file and no internet connection - Given there is connected user "user" + Given there is user "user" which just logged in And there is database file for "user" And there is no internet connection When bridge starts @@ -17,7 +17,7 @@ Feature: Start bridge And "user" has running event loop Scenario: Start with connected user, no database file and internet connection - Given there is connected user "user" + Given there is user "user" which just logged in And there is no database file for "user" When bridge starts Then "user" is connected @@ -25,7 +25,7 @@ Feature: Start bridge And "user" has running event loop Scenario: Start with connected user, no database file and no internet connection - Given there is connected user "user" + Given there is user "user" which just logged in And there is no database file for "user" And there is no internet connection When bridge starts diff --git a/test/features/bridge/users/delete.feature b/test/features/bridge/users/delete.feature index 770ddf6d..be7dc8d1 100644 --- a/test/features/bridge/users/delete.feature +++ b/test/features/bridge/users/delete.feature @@ -1,18 +1,18 @@ Feature: Delete user Scenario: Deleting connected user - Given there is connected user "user" + Given there is user "user" which just logged in When user deletes "user" Then last response is "OK" And "user" has database file Scenario: Deleting connected user with cache - Given there is connected user "user" + Given there is user "user" which just logged in When user deletes "user" with cache Then last response is "OK" And "user" does not have database file Scenario: Deleting connected user without database file - Given there is connected user "user" + Given there is user "user" which just logged in And there is no database file for "user" When user deletes "user" with cache Then last response is "OK" diff --git a/test/features/bridge/users/relogin.feature b/test/features/bridge/users/relogin.feature index e0b43d79..f1f8b9e0 100644 --- a/test/features/bridge/users/relogin.feature +++ b/test/features/bridge/users/relogin.feature @@ -1,6 +1,6 @@ Feature: Re-login Scenario: Re-login with connected user and database file - Given there is connected user "user" + Given there is user "user" which just logged in And there is database file for "user" When "user" logs in Then last response is "failed to finish login: user is already connected" @@ -9,7 +9,7 @@ Feature: Re-login @ignore Scenario: Re-login with connected user and no database file - Given there is connected user "user" + Given there is user "user" which just logged in And there is no database file for "user" When "user" logs in Then last response is "failed to finish login: user is already connected" diff --git a/test/liveapi/controller.go b/test/liveapi/controller.go index d4664007..9e28f512 100644 --- a/test/liveapi/controller.go +++ b/test/liveapi/controller.go @@ -21,45 +21,36 @@ import ( "net/http" "sync" - "github.com/ProtonMail/proton-bridge/internal/constants" "github.com/ProtonMail/proton-bridge/pkg/pmapi" + "github.com/sirupsen/logrus" ) +// Controller implements PMAPIController interface for specified endpoint. type Controller struct { + log *logrus.Entry // Internal states. lock *sync.RWMutex calls []*fakeCall - pmapiByUsername map[string]pmapi.Client messageIDsByUsername map[string][]string - clientManager pmapi.Manager // State controlled by test. noInternetConnection bool } -func NewController(app string) (*Controller, pmapi.Manager) { - cm := pmapi.New(pmapi.NewConfig(getAppVersionName(app), constants.Version)) +func NewController(_ string) (*Controller, pmapi.Manager) { controller := &Controller{ + log: logrus.WithField("pkg", "live-controller"), lock: &sync.RWMutex{}, calls: []*fakeCall{}, - pmapiByUsername: map[string]pmapi.Client{}, messageIDsByUsername: map[string][]string{}, - clientManager: cm, noInternetConnection: false, } - cm.SetTransport(&fakeTransport{ + persistentClients.manager.SetTransport(&fakeTransport{ ctl: controller, transport: http.DefaultTransport, }) - return controller, cm -} - -func getAppVersionName(app string) string { - if app == "ie" { - return "importExport" - } - return app + return controller, persistentClients.manager } diff --git a/test/liveapi/labels.go b/test/liveapi/labels.go index 105b74e9..974ec085 100644 --- a/test/liveapi/labels.go +++ b/test/liveapi/labels.go @@ -37,9 +37,9 @@ var systemLabelNameToID = map[string]string{ //nolint[gochecknoglobals] } func (ctl *Controller) AddUserLabel(username string, label *pmapi.Label) error { - client, ok := ctl.pmapiByUsername[username] - if !ok { - return fmt.Errorf("user %s does not exist", username) + client, err := getPersistentClient(username) + if err != nil { + return err } label.Exclusive = getLabelExclusive(label.Name) @@ -68,9 +68,9 @@ func (ctl *Controller) getLabelID(username, labelName string) (string, error) { return labelID, nil } - client, ok := ctl.pmapiByUsername[username] - if !ok { - return "", fmt.Errorf("user %s does not exist", username) + client, err := getPersistentClient(username) + if err != nil { + return "", err } labels, err := client.ListLabels(context.Background()) diff --git a/test/liveapi/messages.go b/test/liveapi/messages.go index ed696f81..2487b568 100644 --- a/test/liveapi/messages.go +++ b/test/liveapi/messages.go @@ -19,7 +19,6 @@ package liveapi import ( "context" - "fmt" messageUtils "github.com/ProtonMail/proton-bridge/pkg/message" "github.com/ProtonMail/proton-bridge/pkg/pmapi" @@ -31,9 +30,9 @@ func (ctl *Controller) AddUserMessage(username string, message *pmapi.Message) ( return "", errors.New("add user messages with attachments is not implemented for live") } - client, ok := ctl.pmapiByUsername[username] - if !ok { - return "", fmt.Errorf("user %s does not exist", username) + client, err := getPersistentClient(username) + if err != nil { + return "", err } if message.Flags == 0 { @@ -75,9 +74,9 @@ func (ctl *Controller) AddUserMessage(username string, message *pmapi.Message) ( } func (ctl *Controller) GetMessages(username, labelID string) ([]*pmapi.Message, error) { - client, ok := ctl.pmapiByUsername[username] - if !ok { - return nil, fmt.Errorf("user %s does not exist", username) + client, err := getPersistentClient(username) + if err != nil { + return nil, err } page := 0 diff --git a/test/liveapi/persistent_clients.go b/test/liveapi/persistent_clients.go new file mode 100644 index 00000000..265db81a --- /dev/null +++ b/test/liveapi/persistent_clients.go @@ -0,0 +1,131 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge.Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package liveapi + +import ( + "context" + "fmt" + "math/rand" + "os" + + "github.com/ProtonMail/proton-bridge/internal/constants" + "github.com/ProtonMail/proton-bridge/pkg/pmapi" + "github.com/ProtonMail/proton-bridge/pkg/srp" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +// persistentClients keeps authenticated clients for tests. +// +// We need to reduce the number of authentication done by live tests. +// Before every *scenario* we are creating and authenticating new client. +// This is not necessary for controller purposes. We can reuse the same clients +// for all tests. +// +//nolint[gochecknoglobals] +var persistentClients = struct { + manager pmapi.Manager + byName map[string]pmapi.Client + saltByName map[string]string +}{} + +type persistentClient struct { + pmapi.Client + username string +} + +// AuthDelete is noop. All sessions will be closed in CleanupPersistentClients. +func (pc *persistentClient) AuthDelete(_ context.Context) error { + return nil +} + +// AuthSalt returns cached string. Otherwise after some time there is an error: +// +// Access token does not have sufficient scope +// +// while all other routes works normally. Need to confirm with Aron that this +// is expected behaviour. +func (pc *persistentClient) AuthSalt(_ context.Context) (string, error) { + return persistentClients.saltByName[pc.username], nil +} + +func SetupPersistentClients() { + app := os.Getenv("TEST_APP") + + persistentClients.manager = pmapi.New(pmapi.NewConfig(getAppVersionName(app), constants.Version)) + persistentClients.manager.SetLogging(logrus.WithField("pkg", "liveapi"), logrus.GetLevel() == logrus.TraceLevel) + + persistentClients.byName = map[string]pmapi.Client{} + persistentClients.saltByName = map[string]string{} +} + +func getAppVersionName(app string) string { + if app == "ie" { + return "importExport" + } + return app +} + +func CleanupPersistentClients() { + for username, client := range persistentClients.byName { + if err := client.AuthDelete(context.Background()); err != nil { + logrus.WithError(err). + WithField("username", username). + Error("Failed to logout persistent client") + } + } +} + +func addPersistentClient(username string, password, mailboxPassword []byte) (pmapi.Client, error) { + if cl, ok := persistentClients.byName[username]; ok { + return cl, nil + } + + srp.RandReader = rand.New(rand.NewSource(42)) //nolint[gosec] It is OK to use weaker random number generator here + + client, _, err := persistentClients.manager.NewClientWithLogin(context.Background(), username, password) + if err != nil { + return nil, errors.Wrap(err, "failed to create new persistent client") + } + + salt, err := client.AuthSalt(context.Background()) + if err != nil { + return nil, errors.Wrap(err, "persistent client: failed to get salt") + } + + hashedMboxPass, err := pmapi.HashMailboxPassword(mailboxPassword, salt) + if err != nil { + return nil, errors.Wrap(err, "persistent client: failed to hash mailbox password") + } + + if err := client.Unlock(context.Background(), hashedMboxPass); err != nil { + return nil, errors.Wrap(err, "persistent client: failed to unlock user") + } + + persistentClients.byName[username] = client + persistentClients.saltByName[username] = salt + return client, nil +} + +func getPersistentClient(username string) (pmapi.Client, error) { + v, ok := persistentClients.byName[username] + if !ok { + return nil, fmt.Errorf("user %s does not exist", username) + } + return &persistentClient{v, username}, nil +} diff --git a/test/liveapi/users.go b/test/liveapi/users.go index eac77afa..b85aaa5b 100644 --- a/test/liveapi/users.go +++ b/test/liveapi/users.go @@ -21,43 +21,42 @@ import ( "context" "github.com/ProtonMail/proton-bridge/pkg/pmapi" + "github.com/ProtonMail/proton-bridge/test/accounts" "github.com/cucumber/godog" "github.com/pkg/errors" ) -func (ctl *Controller) AddUser(user *pmapi.User, addresses *pmapi.AddressList, password []byte, twoFAEnabled bool) error { - if twoFAEnabled { +func (ctl *Controller) AddUser(account *accounts.TestAccount) error { + if account.IsTwoFAEnabled() { return godog.ErrPending } - client, _, err := ctl.clientManager.NewClientWithLogin(context.Background(), user.Name, password) + client, err := addPersistentClient(account.User().Name, account.Password(), account.MailboxPassword()) if err != nil { - return errors.Wrap(err, "failed to create new client") + return errors.Wrap(err, "failed to add persistent client") } - salt, err := client.AuthSalt(context.Background()) - if err != nil { - return errors.Wrap(err, "failed to get salt") - } - - mailboxPassword, err := pmapi.HashMailboxPassword(password, salt) - if err != nil { - return errors.Wrap(err, "failed to hash mailbox password") - } - - if err := client.Unlock(context.Background(), mailboxPassword); err != nil { - return errors.Wrap(err, "failed to unlock user") - } - - if err := cleanup(client, addresses); err != nil { + if err := cleanup(client, account.Addresses()); err != nil { return errors.Wrap(err, "failed to clean user") } - ctl.pmapiByUsername[user.Name] = client - return nil } func (ctl *Controller) ReorderAddresses(user *pmapi.User, addressIDs []string) error { - return ctl.pmapiByUsername[user.Name].ReorderAddresses(context.Background(), addressIDs) + client, err := getPersistentClient(user.Name) + if err != nil { + return err + } + return client.ReorderAddresses(context.Background(), addressIDs) +} + +func (ctl *Controller) GetAuthClient(username string) pmapi.Client { + client, err := getPersistentClient(username) + if err != nil { + ctl.log.WithError(err). + WithField("username", username). + Fatal("Cannot get authenticated client") + } + return client } diff --git a/test/users_setup_test.go b/test/users_setup_test.go index 5ccfdc58..2c56fa0a 100644 --- a/test/users_setup_test.go +++ b/test/users_setup_test.go @@ -28,6 +28,7 @@ import ( func UsersSetupFeatureContext(s *godog.Suite) { s.Step(`^there is user "([^"]*)"$`, thereIsUser) s.Step(`^there is connected user "([^"]*)"$`, thereIsConnectedUser) + s.Step(`^there is user "([^"]*)" which just logged in$`, thereIsUserWhichJustLoggedIn) s.Step(`^there is disconnected user "([^"]*)"$`, thereIsDisconnectedUser) s.Step(`^there is database file for "([^"]*)"$`, thereIsDatabaseFileForUser) s.Step(`^there is no database file for "([^"]*)"$`, thereIsNoDatabaseFileForUser) @@ -39,7 +40,7 @@ func thereIsUser(bddUserID string) error { if account == nil { return godog.ErrPending } - err := ctx.GetPMAPIController().AddUser(account.User(), account.Addresses(), account.Password(), account.IsTwoFAEnabled()) + err := ctx.GetPMAPIController().AddUser(account) return internalError(err, "adding user %s", account.Username()) } @@ -48,7 +49,21 @@ func thereIsConnectedUser(bddUserID string) error { if account == nil { return godog.ErrPending } - err := ctx.GetPMAPIController().AddUser(account.User(), account.Addresses(), account.Password(), account.IsTwoFAEnabled()) + username := account.Username() + ctl := ctx.GetPMAPIController() + err := ctl.AddUser(account) + if err != nil { + return internalError(err, "adding user %s", username) + } + return ctx.FinishLogin(ctx.GetPMAPIController().GetAuthClient(username), account.MailboxPassword()) +} + +func thereIsUserWhichJustLoggedIn(bddUserID string) error { + account := ctx.GetTestAccount(bddUserID) + if account == nil { + return godog.ErrPending + } + err := ctx.GetPMAPIController().AddUser(account) if err != nil { return internalError(err, "adding user %s", account.Username()) } @@ -60,7 +75,7 @@ func thereIsDisconnectedUser(bddUserID string) error { if account == nil { return godog.ErrPending } - err := ctx.GetPMAPIController().AddUser(account.User(), account.Addresses(), account.Password(), account.IsTwoFAEnabled()) + err := ctx.GetPMAPIController().AddUser(account) if err != nil { return internalError(err, "adding user %s", account.Username()) } From f0ee82fdd23cc21ab3c67cddf303cc376998637e Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 28 May 2021 09:59:31 +0200 Subject: [PATCH 5/8] GODT-1166: Preliminary disable IMAP/SMTP blocking feature. --- internal/imap/server_test.go | 52 ---------- internal/serverutil/mocks/server.go | 150 ---------------------------- internal/serverutil/server.go | 83 --------------- internal/serverutil/server_test.go | 35 ------- internal/smtp/server_test.go | 43 -------- test/context/users.go | 2 +- test/liveapi/persistent_clients.go | 2 +- 7 files changed, 2 insertions(+), 365 deletions(-) delete mode 100644 internal/imap/server_test.go delete mode 100644 internal/serverutil/mocks/server.go delete mode 100644 internal/serverutil/server_test.go delete mode 100644 internal/smtp/server_test.go diff --git a/internal/imap/server_test.go b/internal/imap/server_test.go deleted file mode 100644 index 1653cbd2..00000000 --- a/internal/imap/server_test.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2021 Proton Technologies AG -// -// This file is part of ProtonMail Bridge. -// -// ProtonMail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ProtonMail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with ProtonMail Bridge. If not, see . - -package imap - -import ( - "fmt" - "testing" - - "github.com/ProtonMail/proton-bridge/internal/bridge" - "github.com/ProtonMail/proton-bridge/internal/config/useragent" - "github.com/ProtonMail/proton-bridge/internal/serverutil/mocks" - imapserver "github.com/emersion/go-imap/server" - - "github.com/stretchr/testify/require" -) - -func TestIMAPServerTurnOffAndOnAgain(t *testing.T) { - r := require.New(t) - ts := mocks.NewTestServer(12345) - - server := imapserver.New(nil) - server.Addr = fmt.Sprintf("%v:%v", bridge.Host, ts.WantPort) - - s := &imapServer{ - panicHandler: ts.PanicHandler, - server: server, - port: ts.WantPort, - eventListener: ts.EventListener, - userAgent: useragent.New(), - } - s.isRunning.Store(false) - - r.True(ts.IsPortFree()) - - go s.ListenAndServe() - ts.RunServerTests(r) -} diff --git a/internal/serverutil/mocks/server.go b/internal/serverutil/mocks/server.go deleted file mode 100644 index 8e60c33c..00000000 --- a/internal/serverutil/mocks/server.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2021 Proton Technologies AG -// -// This file is part of ProtonMail Bridge. -// -// ProtonMail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ProtonMail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with ProtonMail Bridge. If not, see . - -package mocks - -import ( - "fmt" - "net/http" - "sync/atomic" - "time" - - "github.com/ProtonMail/proton-bridge/internal/events" - "github.com/ProtonMail/proton-bridge/pkg/listener" - "github.com/ProtonMail/proton-bridge/pkg/ports" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" -) - -type DummyPanicHandler struct{} - -func (ph *DummyPanicHandler) HandlePanic() {} - -type TestServer struct { - PanicHandler *DummyPanicHandler - WantPort int - EventListener listener.Listener - - isRunning atomic.Value - srv *http.Server -} - -func NewTestServer(port int) *TestServer { - s := &TestServer{ - PanicHandler: &DummyPanicHandler{}, - EventListener: listener.New(), - WantPort: ports.FindFreePortFrom(port), - } - s.isRunning.Store(false) - return s -} - -func (s *TestServer) IsPortFree() bool { - return true -} - -func (s *TestServer) IsPortOccupied() bool { - return true -} - -func (s *TestServer) Emit(event string, try, iEvt int) int { - // Emit has separate go routine so it is needed to wait here to - // prevent event race condition. - time.Sleep(100 * time.Millisecond) - iEvt++ - s.EventListener.Emit(event, fmt.Sprintf("%d:%d", try, iEvt)) - return iEvt -} - -func (s *TestServer) HandlePanic() {} -func (s *TestServer) DisconnectUser(string) {} -func (s *TestServer) Port() int { return s.WantPort } -func (s *TestServer) IsRunning() bool { return s.isRunning.Load().(bool) } - -func (s *TestServer) ListenRetryAndServe(retries int, retryAfter time.Duration) { - if s.isRunning.Load().(bool) { - return - } - s.isRunning.Store(true) - - // There can be delay when starting server - time.Sleep(200 * time.Millisecond) - - s.srv = &http.Server{ - Addr: fmt.Sprintf("127.0.0.1:%d", s.WantPort), - } - - err := s.srv.ListenAndServe() - if err != nil { - s.isRunning.Store(false) - if retries > 0 { - time.Sleep(retryAfter) - s.ListenRetryAndServe(retries-1, retryAfter) - } - } - - if s.IsRunning() { - logrus.Error("Not serving but isRunning is true") - s.isRunning.Store(false) - } -} - -func (s *TestServer) Close() { - if !s.isRunning.Load().(bool) { - return - } - s.isRunning.Store(false) - - // There can be delay when stopping server - time.Sleep(200 * time.Millisecond) - if err := s.srv.Close(); err != nil { - logrus.WithError(err).Error("Closing dummy server") - } -} - -func (s *TestServer) RunServerTests(r *require.Assertions) { - // NOTE About choosing tick durations: - // In order to avoid ticks to synchronise and cause occasional race - // condition we choose the tick duration around 100ms but not exactly - // to have large common multiple. - r.Eventually(s.IsPortOccupied, 5*time.Second, 97*time.Millisecond) - - // There was an issue where second time we were not able to restore server. - for try := 0; try < 3; try++ { - i := s.Emit(events.InternetOffEvent, try, 0) - r.Eventually(s.IsPortFree, 10*time.Second, 99*time.Millisecond, "signal off try %d : %d", try, i) - - i = s.Emit(events.InternetOnEvent, try, i) - i = s.Emit(events.InternetOffEvent, try, i) - i = s.Emit(events.InternetOffEvent, try, i) - i = s.Emit(events.InternetOffEvent, try, i) - i = s.Emit(events.InternetOffEvent, try, i) - i = s.Emit(events.InternetOnEvent, try, i) - i = s.Emit(events.InternetOnEvent, try, i) - i = s.Emit(events.InternetOffEvent, try, i) - // Wait a bit longer if needed to process all events - r.Eventually(s.IsPortFree, 20*time.Second, 101*time.Millisecond, "again signal off number %d : %d", try, i) - - i = s.Emit(events.InternetOnEvent, try, i) - r.Eventually(s.IsPortOccupied, 10*time.Second, 103*time.Millisecond, "signal on number %d : %d", try, i) - - i = s.Emit(events.InternetOffEvent, try, i) - i = s.Emit(events.InternetOnEvent, try, i) - i = s.Emit(events.InternetOnEvent, try, i) - r.Eventually(s.IsPortOccupied, 10*time.Second, 107*time.Millisecond, "again signal on number %d : %d", try, i) - } -} diff --git a/internal/serverutil/server.go b/internal/serverutil/server.go index 6542194e..a9865036 100644 --- a/internal/serverutil/server.go +++ b/internal/serverutil/server.go @@ -22,18 +22,12 @@ import ( "github.com/ProtonMail/proton-bridge/internal/events" "github.com/ProtonMail/proton-bridge/pkg/listener" - "github.com/ProtonMail/proton-bridge/pkg/ports" - "github.com/sirupsen/logrus" ) // Server which can handle disconnected users and lost internet connection. type Server interface { - HandlePanic() DisconnectUser(string) ListenRetryAndServe(int, time.Duration) - Close() - Port() int - IsRunning() bool } func monitorDisconnectedUsers(s Server, l listener.Listener) { @@ -44,87 +38,10 @@ func monitorDisconnectedUsers(s Server, l listener.Listener) { } } -func redirectInternetEventsToOneChannel(l listener.Listener) (isInternetOn chan bool) { - on := make(chan string) - l.Add(events.InternetOnEvent, on) - off := make(chan string) - l.Add(events.InternetOffEvent, off) - - // Redirect two channels into one. When select was used the algorithm - // first read all on channels and then read all off channels. - isInternetOn = make(chan bool, 20) - go func() { - for { - logrus.WithField("try", <-on).Trace("Internet ON") - isInternetOn <- true - } - }() - - go func() { - for { - logrus.WithField("try", <-off).Trace("Internet OFF") - isInternetOn <- false - } - }() - return -} - -const ( - recheckPortAfter = 50 * time.Millisecond - stopPortChecksAfter = 15 * time.Second - retryListenerAfter = 5 * time.Second -) - -func monitorInternetConnection(s Server, l listener.Listener) { - isInternetOn := redirectInternetEventsToOneChannel(l) - for { - var expectedIsPortFree bool - if <-isInternetOn { - if s.IsRunning() { - continue - } - go func() { - defer s.HandlePanic() - // We had issues on Mac that from time to time something - // blocked our port for a bit after we closed IMAP server - // due to connection issues. - // Restart always helped, so we do retry to not bother user. - s.ListenRetryAndServe(10, retryListenerAfter) - }() - expectedIsPortFree = false - } else { - if !s.IsRunning() { - continue - } - s.Close() - expectedIsPortFree = true - } - start := time.Now() - for { - isPortFree := ports.IsPortFree(s.Port()) - logrus. - WithField("port", s.Port()). - WithField("isFree", isPortFree). - WithField("wantToBeFree", expectedIsPortFree). - Trace("Check port") - if isPortFree == expectedIsPortFree { - break - } - // Safety stop if something went wrong. - if time.Since(start) > stopPortChecksAfter { - logrus.WithField("expectedIsPortFree", expectedIsPortFree).Warn("Server start/stop check timeouted") - break - } - time.Sleep(recheckPortAfter) - } - } -} - // ListenAndServe starts the server and keeps it on based on internet // availability. It also monitors and disconnect users if requested. func ListenAndServe(s Server, l listener.Listener) { go monitorDisconnectedUsers(s, l) - go monitorInternetConnection(s, l) // When starting the Bridge, we don't want to retry to notify user // quickly about the issue. Very probably retry will not help anyway. diff --git a/internal/serverutil/server_test.go b/internal/serverutil/server_test.go deleted file mode 100644 index fa04a06f..00000000 --- a/internal/serverutil/server_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2021 Proton Technologies AG -// -// This file is part of ProtonMail Bridge. -// -// ProtonMail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ProtonMail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with ProtonMail Bridge. If not, see . - -package serverutil - -import ( - "testing" - - "github.com/ProtonMail/proton-bridge/internal/serverutil/mocks" - "github.com/stretchr/testify/require" -) - -func TestServerTurnOffAndOnAgain(t *testing.T) { - r := require.New(t) - s := mocks.NewTestServer(12321) - - r.True(s.IsPortFree()) - - go ListenAndServe(s, s.EventListener) - s.RunServerTests(r) -} diff --git a/internal/smtp/server_test.go b/internal/smtp/server_test.go deleted file mode 100644 index 3342d21c..00000000 --- a/internal/smtp/server_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2021 Proton Technologies AG -// -// This file is part of ProtonMail Bridge. -// -// ProtonMail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ProtonMail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with ProtonMail Bridge. If not, see . - -package smtp - -import ( - "testing" - - "github.com/ProtonMail/proton-bridge/internal/serverutil/mocks" - - "github.com/stretchr/testify/require" -) - -func TestSMTPServerTurnOffAndOnAgain(t *testing.T) { - r := require.New(t) - ts := mocks.NewTestServer(12342) - - s := &Server{ - panicHandler: ts.PanicHandler, - port: ts.WantPort, - eventListener: ts.EventListener, - } - s.isRunning.Store(false) - - r.True(ts.IsPortFree()) - - go s.ListenAndServe() - ts.RunServerTests(r) -} diff --git a/test/context/users.go b/test/context/users.go index cea3601e..ee8d2db5 100644 --- a/test/context/users.go +++ b/test/context/users.go @@ -63,7 +63,7 @@ func (ctx *TestContext) LoginUser(username string, password, mailboxPassword []b } // FinishLogin prevents authentication if not necessary. -func (ctx *TestContext) FinishLogin(client pmapi.Client, mailboxPassword string) error { +func (ctx *TestContext) FinishLogin(client pmapi.Client, mailboxPassword []byte) error { user, err := ctx.users.FinishLogin(client, client.GetCurrentAuth(), mailboxPassword) if err != nil { return errors.Wrap(err, "failed to finish login") diff --git a/test/liveapi/persistent_clients.go b/test/liveapi/persistent_clients.go index 265db81a..404d76b2 100644 --- a/test/liveapi/persistent_clients.go +++ b/test/liveapi/persistent_clients.go @@ -23,9 +23,9 @@ import ( "math/rand" "os" + "github.com/ProtonMail/go-srp" "github.com/ProtonMail/proton-bridge/internal/constants" "github.com/ProtonMail/proton-bridge/pkg/pmapi" - "github.com/ProtonMail/proton-bridge/pkg/srp" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) From 21dcac9fac7927ccfb97d9ef20e51447dfd3ebef Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 28 May 2021 09:59:31 +0200 Subject: [PATCH 6/8] GODT-1187: Remove IMAP/SMTP blocking when no internet. --- internal/imap/server.go | 212 ++++++-------------- internal/serverutil/controller.go | 117 +++++++++++ internal/serverutil/error_logger.go | 39 ++++ internal/serverutil/listener.go | 59 ++++++ internal/serverutil/protocol.go | 26 +++ internal/serverutil/server.go | 40 ++-- internal/serverutil/test/controller_test.go | 153 ++++++++++++++ internal/serverutil/test/server.go | 88 ++++++++ internal/smtp/server.go | 159 +++++---------- test/features/bridge/no_internet.feature | 32 --- 10 files changed, 604 insertions(+), 321 deletions(-) create mode 100644 internal/serverutil/controller.go create mode 100644 internal/serverutil/error_logger.go create mode 100644 internal/serverutil/listener.go create mode 100644 internal/serverutil/protocol.go create mode 100644 internal/serverutil/test/controller_test.go create mode 100644 internal/serverutil/test/server.go delete mode 100644 test/features/bridge/no_internet.feature diff --git a/internal/imap/server.go b/internal/imap/server.go index 7dfb3caf..a6cecd3c 100644 --- a/internal/imap/server.go +++ b/internal/imap/server.go @@ -23,13 +23,11 @@ import ( "io" "net" "strings" - "sync/atomic" "time" imapid "github.com/ProtonMail/go-imap-id" "github.com/ProtonMail/proton-bridge/internal/bridge" "github.com/ProtonMail/proton-bridge/internal/config/useragent" - "github.com/ProtonMail/proton-bridge/internal/events" "github.com/ProtonMail/proton-bridge/internal/imap/id" "github.com/ProtonMail/proton-bridge/internal/imap/idle" "github.com/ProtonMail/proton-bridge/internal/imap/uidplus" @@ -43,43 +41,58 @@ import ( "github.com/emersion/go-imap/backend" imapserver "github.com/emersion/go-imap/server" "github.com/emersion/go-sasl" - "github.com/sirupsen/logrus" ) -type imapServer struct { - panicHandler panicHandler - server *imapserver.Server - userAgent *useragent.UserAgent - eventListener listener.Listener - debugClient bool - debugServer bool - port int - isRunning atomic.Value +// Server takes care of IMAP listening serving. It implements serverutil.Server. +type Server struct { + panicHandler panicHandler + userAgent *useragent.UserAgent + debugClient bool + debugServer bool + port int + + server *imapserver.Server + controller serverutil.Controller } // NewIMAPServer constructs a new IMAP server configured with the given options. -func NewIMAPServer(panicHandler panicHandler, debugClient, debugServer bool, port int, tls *tls.Config, imapBackend backend.Backend, userAgent *useragent.UserAgent, eventListener listener.Listener) *imapServer { // nolint[golint] - s := imapserver.New(imapBackend) - s.Addr = fmt.Sprintf("%v:%v", bridge.Host, port) - s.TLSConfig = tls - s.AllowInsecureAuth = true - s.ErrorLog = newServerErrorLogger("server-imap") - s.AutoLogout = 30 * time.Minute - - if debugServer { - fmt.Println("THE LOG WILL CONTAIN **DECRYPTED** MESSAGE DATA") - log.Warning("================================================") - log.Warning("THIS LOG WILL CONTAIN **DECRYPTED** MESSAGE DATA") - log.Warning("================================================") +func NewIMAPServer( + panicHandler panicHandler, + debugClient, debugServer bool, + port int, + tls *tls.Config, + imapBackend backend.Backend, + userAgent *useragent.UserAgent, + eventListener listener.Listener, +) *Server { + server := &Server{ + panicHandler: panicHandler, + userAgent: userAgent, + debugClient: debugClient, + debugServer: debugServer, + port: port, } + server.server = newGoIMAPServer(tls, imapBackend, server.Address(), userAgent) + server.controller = serverutil.NewController(server, eventListener) + return server +} + +func newGoIMAPServer(tls *tls.Config, backend backend.Backend, address string, userAgent *useragent.UserAgent) *imapserver.Server { + server := imapserver.New(backend) + server.TLSConfig = tls + server.AllowInsecureAuth = true + server.ErrorLog = serverutil.NewServerErrorLogger(serverutil.IMAP) + server.AutoLogout = 30 * time.Minute + server.Addr = address + serverID := imapid.ID{ imapid.FieldName: "ProtonMail Bridge", imapid.FieldVendor: "Proton Technologies AG", imapid.FieldSupportURL: "https://protonmail.com/support", } - s.EnableAuth(sasl.Login, func(conn imapserver.Conn) sasl.Server { + server.EnableAuth(sasl.Login, func(conn imapserver.Conn) sasl.Server { return sasl.NewLoginServer(func(address, password string) error { user, err := conn.Server().Backend.Login(nil, address, password) if err != nil { @@ -93,7 +106,7 @@ func NewIMAPServer(panicHandler panicHandler, debugClient, debugServer bool, por }) }) - s.Enable( + server.Enable( idle.NewExtension(), imapmove.NewExtension(), id.NewExtension(serverID, userAgent), @@ -103,87 +116,35 @@ func NewIMAPServer(panicHandler panicHandler, debugClient, debugServer bool, por uidplus.NewExtension(), ) - server := &imapServer{ - panicHandler: panicHandler, - server: s, - userAgent: userAgent, - eventListener: eventListener, - debugClient: debugClient, - debugServer: debugServer, - port: port, - } - server.isRunning.Store(false) return server } -func (s *imapServer) HandlePanic() { s.panicHandler.HandlePanic() } -func (s *imapServer) IsRunning() bool { return s.isRunning.Load().(bool) } -func (s *imapServer) Port() int { return s.port } +// ListenAndServe will run server and all monitors. +func (s *Server) ListenAndServe() { s.controller.ListenAndServe() } -// ListenAndServe starts the server and keeps it on based on internet -// availability. -func (s *imapServer) ListenAndServe() { - serverutil.ListenAndServe(s, s.eventListener) -} +// Close turns off server and monitors. +func (s *Server) Close() { s.controller.Close() } -// ListenRetryAndServe will start listener. If port is occupied it will try -// again after coolDown time. Once listener is OK it will serve. -func (s *imapServer) ListenRetryAndServe(retries int, retryAfter time.Duration) { - if s.IsRunning() { - return - } - s.isRunning.Store(true) +// Implements serverutil.Server interface. - l := log.WithField("address", s.server.Addr) - l.Info("IMAP server is starting") - listener, err := net.Listen("tcp", s.server.Addr) - if err != nil { - s.isRunning.Store(false) - if retries > 0 { - l.WithError(err).WithField("retries", retries).Warn("IMAP listener failed") - time.Sleep(retryAfter) - s.ListenRetryAndServe(retries-1, retryAfter) - return - } +func (Server) Protocol() serverutil.Protocol { return serverutil.IMAP } +func (s *Server) UseSSL() bool { return false } +func (s *Server) Address() string { return fmt.Sprintf("%s:%d", bridge.Host, s.port) } +func (s *Server) TLSConfig() *tls.Config { return s.server.TLSConfig } +func (s *Server) HandlePanic() { s.panicHandler.HandlePanic() } - l.WithError(err).Error("IMAP listener failed") - s.eventListener.Emit(events.ErrorEvent, "IMAP failed: "+err.Error()) - return - } +func (s *Server) DebugServer() bool { return s.debugServer } +func (s *Server) DebugClient() bool { return s.debugClient } - err = s.server.Serve(&connListener{ - Listener: listener, - server: s, - userAgent: s.userAgent, - }) - // Serve returns error every time, even after closing the server. - // User shouldn't be notified about error if server shouldn't be running, - // but it should in case it was not closed by `s.Close()`. - if err != nil && s.IsRunning() { - s.isRunning.Store(false) - l.WithError(err).Error("IMAP server failed") - s.eventListener.Emit(events.ErrorEvent, "IMAP failed: "+err.Error()) - return - } - defer s.server.Close() //nolint[errcheck] +func (s *Server) SetLoggers(localDebug, remoteDebug io.Writer) { + s.server.Debug = imap.NewDebugWriter(localDebug, remoteDebug) - l.Info("IMAP server stopped") -} - -// Stops the server. -func (s *imapServer) Close() { - if !s.IsRunning() { - return - } - s.isRunning.Store(false) - - log.Info("Closing IMAP server") - if err := s.server.Close(); err != nil { - log.WithError(err).Error("Failed to close the connection") + if !s.userAgent.HasClient() { + s.userAgent.SetClient("UnknownClient", "0.0.1") } } -func (s *imapServer) DisconnectUser(address string) { +func (s *Server) DisconnectUser(address string) { log.Info("Disconnecting all open IMAP connections for ", address) s.server.ForEachConn(func(conn imapserver.Conn) { connUser := conn.Context().User @@ -195,60 +156,5 @@ func (s *imapServer) DisconnectUser(address string) { }) } -// connListener sets debug loggers on server containing fields with local -// and remote addresses right after new connection is accepted. -type connListener struct { - net.Listener - - server *imapServer - userAgent *useragent.UserAgent -} - -func (l *connListener) Accept() (net.Conn, error) { - conn, err := l.Listener.Accept() - - if err == nil && (l.server.debugServer || l.server.debugClient) { - debugLog := log - if addr := conn.LocalAddr(); addr != nil { - debugLog = debugLog.WithField("loc", addr.String()) - } - if addr := conn.RemoteAddr(); addr != nil { - debugLog = debugLog.WithField("rem", addr.String()) - } - - var localDebug, remoteDebug io.Writer - if l.server.debugServer { - localDebug = debugLog.WithField("pkg", "imap/server").WriterLevel(logrus.DebugLevel) - } - if l.server.debugClient { - remoteDebug = debugLog.WithField("pkg", "imap/client").WriterLevel(logrus.DebugLevel) - } - - l.server.server.Debug = imap.NewDebugWriter(localDebug, remoteDebug) - } - - if !l.userAgent.HasClient() { - l.userAgent.SetClient("UnknownClient", "0.0.1") - } - - return conn, err -} - -// serverErrorLogger implements go-imap/logger interface. -type serverErrorLogger struct { - tag string -} - -func newServerErrorLogger(tag string) *serverErrorLogger { - return &serverErrorLogger{tag} -} - -func (s *serverErrorLogger) Printf(format string, args ...interface{}) { - err := fmt.Sprintf(format, args...) - log.WithField("pkg", s.tag).Error(err) -} - -func (s *serverErrorLogger) Println(args ...interface{}) { - err := fmt.Sprintln(args...) - log.WithField("pkg", s.tag).Error(err) -} +func (s *Server) Serve(listener net.Listener) error { return s.server.Serve(listener) } +func (s *Server) StopServe() error { return s.server.Close() } diff --git a/internal/serverutil/controller.go b/internal/serverutil/controller.go new file mode 100644 index 00000000..c2ba1dca --- /dev/null +++ b/internal/serverutil/controller.go @@ -0,0 +1,117 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package serverutil + +import ( + "crypto/tls" + "fmt" + "net" + + "github.com/ProtonMail/proton-bridge/internal/events" + "github.com/ProtonMail/proton-bridge/pkg/listener" + "github.com/sirupsen/logrus" +) + +// Controller will make sure that server is listening and serving and if needed +// users are disconnected. +type Controller interface { + ListenAndServe() + Close() +} + +// NewController return simple server controller. +func NewController(s Server, l listener.Listener) Controller { + log := logrus.WithField("pkg", "serverutil").WithField("protocol", s.Protocol()) + c := &controller{ + server: s, + signals: l, + log: log, + closeDisconnectUsers: make(chan void), + } + + if s.DebugServer() { + fmt.Println("THE LOG WILL CONTAIN **DECRYPTED** MESSAGE DATA") + log.Warning("================================================") + log.Warning("THIS LOG WILL CONTAIN **DECRYPTED** MESSAGE DATA") + log.Warning("================================================") + } + + return c +} + +type void struct{} + +type controller struct { + server Server + signals listener.Listener + log *logrus.Entry + + closeDisconnectUsers chan void +} + +func (c *controller) Close() { + c.closeDisconnectUsers <- void{} + if err := c.server.StopServe(); err != nil { + c.log.WithError(err).Error("Issue when closing server") + } +} + +// ListenAndServe starts the server and keeps it on based on internet +// availability. It also monitors and disconnect users if requested. +func (c *controller) ListenAndServe() { + go monitorDisconnectedUsers(c.server, c.signals, c.closeDisconnectUsers) + + defer c.server.HandlePanic() + + l := c.log.WithField("useSSL", c.server.UseSSL()). + WithField("address", c.server.Address()) + + var listener net.Listener + var err error + + if c.server.UseSSL() { + listener, err = tls.Listen("tcp", c.server.Address(), c.server.TLSConfig()) + } else { + listener, err = net.Listen("tcp", c.server.Address()) + } + + if err != nil { + l.WithError(err).Error("Cannot start listner.") + c.signals.Emit(events.ErrorEvent, string(c.server.Protocol())+" failed: "+err.Error()) + return + } + + // When starting the Bridge, we don't want to retry to notify user + // quickly about the issue. Very probably retry will not help anyway. + l.Info("Starting server") + err = c.server.Serve(&connListener{listener, c.server}) + l.WithError(err).Debug("GoSMTP not serving") +} + +func monitorDisconnectedUsers(s Server, l listener.Listener, done <-chan void) { + ch := make(chan string) + l.Add(events.CloseConnectionEvent, ch) + for { + select { + case <-done: + return + case address := <-ch: + s.DisconnectUser(address) + } + } +} diff --git a/internal/serverutil/error_logger.go b/internal/serverutil/error_logger.go new file mode 100644 index 00000000..576f2d84 --- /dev/null +++ b/internal/serverutil/error_logger.go @@ -0,0 +1,39 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package serverutil + +import ( + "github.com/sirupsen/logrus" +) + +// ServerErrorLogger implements go-imap/logger interface. +type ServerErrorLogger struct { + l *logrus.Entry +} + +func NewServerErrorLogger(protocol Protocol) *ServerErrorLogger { + return &ServerErrorLogger{l: logrus.WithField("protocol", protocol)} +} + +func (s *ServerErrorLogger) Printf(format string, args ...interface{}) { + s.l.Errorf(format, args...) +} + +func (s *ServerErrorLogger) Println(args ...interface{}) { + s.l.Errorln(args...) +} diff --git a/internal/serverutil/listener.go b/internal/serverutil/listener.go new file mode 100644 index 00000000..53450205 --- /dev/null +++ b/internal/serverutil/listener.go @@ -0,0 +1,59 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package serverutil + +import ( + "io" + "net" + + "github.com/sirupsen/logrus" +) + +// connListener sets debug loggers on server containing fields with local +// and remote addresses right after new connection is accepted. +type connListener struct { + net.Listener + + server Server +} + +func (l *connListener) Accept() (net.Conn, error) { + conn, err := l.Listener.Accept() + + if err == nil && (l.server.DebugServer() || l.server.DebugClient()) { + debugLog := logrus.WithField("pkg", l.server.Protocol()) + if addr := conn.LocalAddr(); addr != nil { + debugLog = debugLog.WithField("loc", addr.String()) + } + if addr := conn.RemoteAddr(); addr != nil { + debugLog = debugLog.WithField("rem", addr.String()) + } + + var localDebug, remoteDebug io.Writer + if l.server.DebugServer() { + localDebug = debugLog.WithField("comm", "server").WriterLevel(logrus.DebugLevel) + } + if l.server.DebugClient() { + remoteDebug = debugLog.WithField("comm", "client").WriterLevel(logrus.DebugLevel) + } + + l.server.SetLoggers(localDebug, remoteDebug) + } + + return conn, err +} diff --git a/internal/serverutil/protocol.go b/internal/serverutil/protocol.go new file mode 100644 index 00000000..c551359f --- /dev/null +++ b/internal/serverutil/protocol.go @@ -0,0 +1,26 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package serverutil + +type Protocol string + +const ( + HTTP = Protocol("HTTP") + IMAP = Protocol("IMAP") + SMTP = Protocol("SMTP") +) diff --git a/internal/serverutil/server.go b/internal/serverutil/server.go index a9865036..e081b032 100644 --- a/internal/serverutil/server.go +++ b/internal/serverutil/server.go @@ -18,32 +18,24 @@ package serverutil import ( - "time" - - "github.com/ProtonMail/proton-bridge/internal/events" - "github.com/ProtonMail/proton-bridge/pkg/listener" + "crypto/tls" + "io" + "net" ) -// Server which can handle disconnected users and lost internet connection. +// Server can handle disconnected users. type Server interface { + Protocol() Protocol + UseSSL() bool + Address() string + TLSConfig() *tls.Config + + DebugServer() bool + DebugClient() bool + SetLoggers(localDebug, remoteDebug io.Writer) + + HandlePanic() DisconnectUser(string) - ListenRetryAndServe(int, time.Duration) -} - -func monitorDisconnectedUsers(s Server, l listener.Listener) { - ch := make(chan string) - l.Add(events.CloseConnectionEvent, ch) - for address := range ch { - s.DisconnectUser(address) - } -} - -// ListenAndServe starts the server and keeps it on based on internet -// availability. It also monitors and disconnect users if requested. -func ListenAndServe(s Server, l listener.Listener) { - go monitorDisconnectedUsers(s, l) - - // When starting the Bridge, we don't want to retry to notify user - // quickly about the issue. Very probably retry will not help anyway. - s.ListenRetryAndServe(0, 0) + Serve(net.Listener) error + StopServe() error } diff --git a/internal/serverutil/test/controller_test.go b/internal/serverutil/test/controller_test.go new file mode 100644 index 00000000..62cab2ec --- /dev/null +++ b/internal/serverutil/test/controller_test.go @@ -0,0 +1,153 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package test + +import ( + "net/http" + "testing" + "time" + + "github.com/ProtonMail/proton-bridge/internal/events" + "github.com/ProtonMail/proton-bridge/internal/serverutil" + "github.com/ProtonMail/proton-bridge/pkg/listener" + "github.com/stretchr/testify/require" +) + +func setup(t *testing.T) (*require.Assertions, *testServer, listener.Listener, serverutil.Controller) { + r := require.New(t) + s := newTestServer() + l := listener.New() + c := serverutil.NewController(s, l) + + return r, s, l, c +} + +func TestControllerListernServeClose(t *testing.T) { + r, s, l, c := setup(t) + + errorCh := l.ProvideChannel(events.ErrorEvent) + + r.True(s.portIsFree()) + go c.ListenAndServe() + r.Eventually(s.portIsOccupied, time.Second, 50*time.Millisecond) + + r.NoError(s.ping()) + + r.Nil(s.localDebug) + r.Nil(s.remoteDebug) + + c.Close() + r.Eventually(s.portIsFree, time.Second, 50*time.Millisecond) + + select { + case msg := <-errorCh: + r.Fail("Expected no error but have %q", msg) + case <-time.Tick(100 * time.Millisecond): + break + } +} + +func TestControllerFailOnBusyPort(t *testing.T) { + r, s, l, c := setup(t) + + ocupator := http.Server{Addr: s.Address()} + defer ocupator.Close() //nolint[errcheck] + + go ocupator.ListenAndServe() //nolint[errcheck] + r.Eventually(s.portIsOccupied, time.Second, 50*time.Millisecond) + + errorCh := l.ProvideChannel(events.ErrorEvent) + go c.ListenAndServe() + + r.Eventually(s.portIsOccupied, time.Second, 50*time.Millisecond) + + select { + case <-errorCh: + break + case <-time.Tick(time.Second): + r.Fail("Expected error but have none.") + } +} + +func TestControllerCallDisconnectUser(t *testing.T) { + r, s, l, c := setup(t) + + go c.ListenAndServe() + r.Eventually(s.portIsOccupied, time.Second, 50*time.Millisecond) + r.NoError(s.ping()) + + l.Emit(events.CloseConnectionEvent, "") + r.Eventually(func() bool { return s.calledDisconnected == 1 }, time.Second, 50*time.Millisecond) + + c.Close() + r.Eventually(s.portIsFree, time.Second, 50*time.Millisecond) + + l.Emit(events.CloseConnectionEvent, "") + r.Equal(1, s.calledDisconnected) +} + +func TestDebugClient(t *testing.T) { + r, s, _, c := setup(t) + + s.debugServer = false + s.debugClient = true + + go c.ListenAndServe() + r.Eventually(s.portIsOccupied, time.Second, 50*time.Millisecond) + r.NoError(s.ping()) + + r.Nil(s.localDebug) + r.NotNil(s.remoteDebug) + + c.Close() + r.Eventually(s.portIsFree, time.Second, 50*time.Millisecond) +} + +func TestDebugServer(t *testing.T) { + r, s, _, c := setup(t) + + s.debugServer = true + s.debugClient = false + + go c.ListenAndServe() + r.Eventually(s.portIsOccupied, time.Second, 50*time.Millisecond) + r.NoError(s.ping()) + + r.NotNil(s.localDebug) + r.Nil(s.remoteDebug) + + c.Close() + r.Eventually(s.portIsFree, time.Second, 50*time.Millisecond) +} + +func TestDebugBoth(t *testing.T) { + r, s, _, c := setup(t) + + s.debugServer = true + s.debugClient = true + + go c.ListenAndServe() + r.Eventually(s.portIsOccupied, time.Second, 50*time.Millisecond) + r.NoError(s.ping()) + + r.NotNil(s.localDebug) + r.NotNil(s.remoteDebug) + + c.Close() + r.Eventually(s.portIsFree, time.Second, 50*time.Millisecond) +} diff --git a/internal/serverutil/test/server.go b/internal/serverutil/test/server.go new file mode 100644 index 00000000..f0615c5d --- /dev/null +++ b/internal/serverutil/test/server.go @@ -0,0 +1,88 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package test + +import ( + "crypto/tls" + "fmt" + "io" + "net" + "net/http" + + "github.com/ProtonMail/proton-bridge/internal/serverutil" + "github.com/ProtonMail/proton-bridge/pkg/ports" +) + +func newTestServer() *testServer { + return &testServer{port: 11188} +} + +type testServer struct { + http http.Server + + useSSL, + debugServer, + debugClient bool + calledDisconnected int + + port int + tls *tls.Config + + localDebug, remoteDebug io.Writer +} + +func (*testServer) Protocol() serverutil.Protocol { return serverutil.HTTP } +func (s *testServer) UseSSL() bool { return s.useSSL } +func (s *testServer) Address() string { return fmt.Sprintf("127.0.0.1:%d", s.port) } +func (s *testServer) TLSConfig() *tls.Config { return s.tls } +func (s *testServer) HandlePanic() {} + +func (s *testServer) DebugServer() bool { return s.debugServer } +func (s *testServer) DebugClient() bool { return s.debugClient } +func (s *testServer) SetLoggers(localDebug, remoteDebug io.Writer) { + s.localDebug = localDebug + s.remoteDebug = remoteDebug +} + +func (s *testServer) DisconnectUser(string) { + s.calledDisconnected++ +} + +func (s *testServer) Serve(l net.Listener) error { + return s.http.Serve(l) +} + +func (s *testServer) StopServe() error { return s.http.Close() } + +func (s *testServer) portIsFree() bool { + return ports.IsPortFree(s.port) +} + +func (s *testServer) portIsOccupied() bool { + return !ports.IsPortFree(s.port) +} + +func (s *testServer) ping() error { + client := &http.Client{} + resp, err := client.Get("http://" + s.Address() + "/ping") + if err != nil { + return err + } + + return resp.Body.Close() +} diff --git a/internal/smtp/server.go b/internal/smtp/server.go index ecb9f2f6..3db68c69 100644 --- a/internal/smtp/server.go +++ b/internal/smtp/server.go @@ -20,72 +20,60 @@ package smtp import ( "crypto/tls" "fmt" + "io" "net" - "sync/atomic" - "time" "github.com/ProtonMail/proton-bridge/internal/bridge" - "github.com/ProtonMail/proton-bridge/internal/events" "github.com/ProtonMail/proton-bridge/internal/serverutil" "github.com/ProtonMail/proton-bridge/pkg/listener" "github.com/emersion/go-sasl" goSMTP "github.com/emersion/go-smtp" - "github.com/sirupsen/logrus" ) // Server is Bridge SMTP server implementation. type Server struct { - panicHandler panicHandler - backend goSMTP.Backend - server *goSMTP.Server - eventListener listener.Listener - debug bool - useSSL bool - port int - tls *tls.Config - isRunning atomic.Value + panicHandler panicHandler + backend goSMTP.Backend + debug bool + useSSL bool + port int + tls *tls.Config + + server *goSMTP.Server + controller serverutil.Controller } // NewSMTPServer returns an SMTP server configured with the given options. -func NewSMTPServer(panicHandler panicHandler, debug bool, port int, useSSL bool, tls *tls.Config, smtpBackend goSMTP.Backend, eventListener listener.Listener) *Server { - if debug { - fmt.Println("THE LOG WILL CONTAIN **DECRYPTED** MESSAGE DATA") - log.Warning("================================================") - log.Warning("THIS LOG WILL CONTAIN **DECRYPTED** MESSAGE DATA") - log.Warning("================================================") +func NewSMTPServer( + panicHandler panicHandler, + debug bool, port int, useSSL bool, + tls *tls.Config, + smtpBackend goSMTP.Backend, + eventListener listener.Listener, +) *Server { + server := &Server{ + panicHandler: panicHandler, + backend: smtpBackend, + debug: debug, + useSSL: useSSL, + port: port, + tls: tls, } - server := &Server{ - panicHandler: panicHandler, - backend: smtpBackend, - eventListener: eventListener, - debug: debug, - useSSL: useSSL, - port: port, - tls: tls, - } - server.isRunning.Store(false) + server.server = newGoSMTPServer(server) + server.controller = serverutil.NewController(server, eventListener) return server } -func (s *Server) HandlePanic() { s.panicHandler.HandlePanic() } -func (s *Server) IsRunning() bool { return s.isRunning.Load().(bool) } -func (s *Server) Port() int { return s.port } - -func newGoSMTPServer(debug bool, smtpBackend goSMTP.Backend, port int, tls *tls.Config) *goSMTP.Server { - newSMTP := goSMTP.NewServer(smtpBackend) - newSMTP.Addr = fmt.Sprintf("%v:%v", bridge.Host, port) - newSMTP.TLSConfig = tls +func newGoSMTPServer(s *Server) *goSMTP.Server { + newSMTP := goSMTP.NewServer(s.backend) + newSMTP.Addr = s.Address() + newSMTP.TLSConfig = s.tls newSMTP.Domain = bridge.Host + newSMTP.ErrorLog = serverutil.NewServerErrorLogger(serverutil.SMTP) newSMTP.AllowInsecureAuth = true newSMTP.MaxLineLength = 1 << 16 - if debug { - newSMTP.Debug = logrus. - WithField("pkg", "smtp/server"). - WriterLevel(logrus.DebugLevel) - } - newSMTP.EnableAuth(sasl.Login, func(conn *goSMTP.Conn) sasl.Server { return sasl.NewLoginServer(func(address, password string) error { user, err := conn.Server().Backend.Login(nil, address, password) @@ -100,80 +88,24 @@ func newGoSMTPServer(debug bool, smtpBackend goSMTP.Backend, port int, tls *tls. return newSMTP } -// ListenAndServe starts the server and keeps it on based on internet -// availability. -func (s *Server) ListenAndServe() { - serverutil.ListenAndServe(s, s.eventListener) -} +// ListenAndServe will run server and all monitors. +func (s *Server) ListenAndServe() { s.controller.ListenAndServe() } -func (s *Server) ListenRetryAndServe(retries int, retryAfter time.Duration) { - if s.IsRunning() { - return - } - s.isRunning.Store(true) +// Close turns off server and monitors. +func (s *Server) Close() { s.controller.Close() } - s.server = newGoSMTPServer(s.debug, s.backend, s.port, s.tls) +// Implements servertutil.Server interface. - l := log.WithField("useSSL", s.useSSL).WithField("address", s.server.Addr) - l.Info("SMTP server is starting") +func (Server) Protocol() serverutil.Protocol { return serverutil.SMTP } +func (s *Server) UseSSL() bool { return s.useSSL } +func (s *Server) Address() string { return fmt.Sprintf("%s:%d", bridge.Host, s.port) } +func (s *Server) TLSConfig() *tls.Config { return s.tls } +func (s *Server) HandlePanic() { s.panicHandler.HandlePanic() } - var listener net.Listener - var err error - if s.useSSL { - listener, err = tls.Listen("tcp", s.server.Addr, s.server.TLSConfig) - } else { - listener, err = net.Listen("tcp", s.server.Addr) - } - l.WithError(err).Debug("Listener for SMTP created") - if err != nil { - s.isRunning.Store(false) - if retries > 0 { - l.WithError(err).WithField("retries", retries).Warn("SMTP listener failed") - time.Sleep(retryAfter) - s.ListenRetryAndServe(retries-1, retryAfter) - return - } +func (s *Server) DebugServer() bool { return s.debug } +func (s *Server) DebugClient() bool { return s.debug } - l.WithError(err).Error("SMTP listener failed") - s.eventListener.Emit(events.ErrorEvent, "SMTP failed: "+err.Error()) - return - } - - err = s.server.Serve(listener) - l.WithError(err).Debug("GoSMTP not serving") - // Serve returns error every time, even after closing the server. - // User shouldn't be notified about error if server shouldn't be running, - // but it should in case it was not closed by `s.Close()`. - if err != nil && s.IsRunning() { - s.isRunning.Store(false) - l.WithError(err).Error("SMTP server failed") - s.eventListener.Emit(events.ErrorEvent, "SMTP failed: "+err.Error()) - return - } - defer func() { - // Go SMTP server instance can be closed only once. Otherwise - // it returns an error. The error is not export therefore we - // will check the string value. - err := s.server.Close() - if err == nil || err.Error() != "smtp: server already closed" { - l.WithError(err).Warn("Server was not closed") - } - }() - - l.Info("SMTP server closed") -} - -// Close stops the server. -func (s *Server) Close() { - if !s.IsRunning() { - return - } - s.isRunning.Store(false) - - if err := s.server.Close(); err != nil { - log.WithError(err).Error("Cannot close the server") - } -} +func (s *Server) SetLoggers(localDebug, remoteDebug io.Writer) { s.server.Debug = localDebug } func (s *Server) DisconnectUser(address string) { log.Info("Disconnecting all open SMTP connections for ", address) @@ -186,3 +118,6 @@ func (s *Server) DisconnectUser(address string) { } }) } + +func (s *Server) Serve(l net.Listener) error { return s.server.Serve(l) } +func (s *Server) StopServe() error { return s.server.Close() } diff --git a/test/features/bridge/no_internet.feature b/test/features/bridge/no_internet.feature deleted file mode 100644 index 4025f9a4..00000000 --- a/test/features/bridge/no_internet.feature +++ /dev/null @@ -1,32 +0,0 @@ -Feature: Servers are closed when no internet - - # FIXME: Locally works, has lags on CI. Looks like it breaks other tests as well. - @ignore - Scenario: All connection are closed and then restored multiple times - Given there is connected user "user" - And there is IMAP client "i1" logged in as "user" - And there is SMTP client "s1" logged in as "user" - When there is no internet connection - And 3 seconds pass - Then IMAP client "i1" is logged out - And SMTP client "s1" is logged out - Given the internet connection is restored - And 3 seconds pass - And there is IMAP client "i2" logged in as "user" - And there is SMTP client "s2" logged in as "user" - When IMAP client "i2" gets info of "INBOX" - When SMTP client "s2" sends "HELO example.com" - Then IMAP response to "i2" is "OK" - Then SMTP response to "s2" is "OK" - When there is no internet connection - And 3 seconds pass - Then IMAP client "i2" is logged out - And SMTP client "s2" is logged out - Given the internet connection is restored - And 3 seconds pass - And there is IMAP client "i3" logged in as "user" - And there is SMTP client "s3" logged in as "user" - When IMAP client "i3" gets info of "INBOX" - When SMTP client "s3" sends "HELO example.com" - Then IMAP response to "i3" is "OK" - Then SMTP response to "s3" is "OK" From a3e102e4564477a10a99b50c2313e15d181b79f2 Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 11 Jun 2021 13:45:00 +0200 Subject: [PATCH 7/8] GODT-1166: Do not expose current auth token in interface --- internal/store/mocks/mocks.go | 96 +++++------ internal/store/mocks/utils_mocks.go | 36 ++-- internal/transfer/mocks/mocks.go | 60 +++---- internal/users/mocks/listener_mocks.go | 36 ++-- internal/users/mocks/mocks.go | 84 ++++----- pkg/message/mocks/mocks.go | 20 +-- pkg/pmapi/client_types.go | 2 - pkg/pmapi/mocks/mocks.go | 230 ++++++++++++------------- test/context/users.go | 11 +- test/liveapi/persistent_clients.go | 22 ++- 10 files changed, 300 insertions(+), 297 deletions(-) diff --git a/internal/store/mocks/mocks.go b/internal/store/mocks/mocks.go index acb846be..7adf0ed3 100644 --- a/internal/store/mocks/mocks.go +++ b/internal/store/mocks/mocks.go @@ -12,89 +12,89 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockPanicHandler is a mock of PanicHandler interface +// MockPanicHandler is a mock of PanicHandler interface. type MockPanicHandler struct { ctrl *gomock.Controller recorder *MockPanicHandlerMockRecorder } -// MockPanicHandlerMockRecorder is the mock recorder for MockPanicHandler +// MockPanicHandlerMockRecorder is the mock recorder for MockPanicHandler. type MockPanicHandlerMockRecorder struct { mock *MockPanicHandler } -// NewMockPanicHandler creates a new mock instance +// NewMockPanicHandler creates a new mock instance. func NewMockPanicHandler(ctrl *gomock.Controller) *MockPanicHandler { mock := &MockPanicHandler{ctrl: ctrl} mock.recorder = &MockPanicHandlerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockPanicHandler) EXPECT() *MockPanicHandlerMockRecorder { return m.recorder } -// HandlePanic mocks base method +// HandlePanic mocks base method. func (m *MockPanicHandler) HandlePanic() { m.ctrl.T.Helper() m.ctrl.Call(m, "HandlePanic") } -// HandlePanic indicates an expected call of HandlePanic +// HandlePanic indicates an expected call of HandlePanic. func (mr *MockPanicHandlerMockRecorder) HandlePanic() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandlePanic", reflect.TypeOf((*MockPanicHandler)(nil).HandlePanic)) } -// MockBridgeUser is a mock of BridgeUser interface +// MockBridgeUser is a mock of BridgeUser interface. type MockBridgeUser struct { ctrl *gomock.Controller recorder *MockBridgeUserMockRecorder } -// MockBridgeUserMockRecorder is the mock recorder for MockBridgeUser +// MockBridgeUserMockRecorder is the mock recorder for MockBridgeUser. type MockBridgeUserMockRecorder struct { mock *MockBridgeUser } -// NewMockBridgeUser creates a new mock instance +// NewMockBridgeUser creates a new mock instance. func NewMockBridgeUser(ctrl *gomock.Controller) *MockBridgeUser { mock := &MockBridgeUser{ctrl: ctrl} mock.recorder = &MockBridgeUserMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockBridgeUser) EXPECT() *MockBridgeUserMockRecorder { return m.recorder } -// CloseAllConnections mocks base method +// CloseAllConnections mocks base method. func (m *MockBridgeUser) CloseAllConnections() { m.ctrl.T.Helper() m.ctrl.Call(m, "CloseAllConnections") } -// CloseAllConnections indicates an expected call of CloseAllConnections +// CloseAllConnections indicates an expected call of CloseAllConnections. func (mr *MockBridgeUserMockRecorder) CloseAllConnections() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseAllConnections", reflect.TypeOf((*MockBridgeUser)(nil).CloseAllConnections)) } -// CloseConnection mocks base method +// CloseConnection mocks base method. func (m *MockBridgeUser) CloseConnection(arg0 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "CloseConnection", arg0) } -// CloseConnection indicates an expected call of CloseConnection +// CloseConnection indicates an expected call of CloseConnection. func (mr *MockBridgeUserMockRecorder) CloseConnection(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseConnection", reflect.TypeOf((*MockBridgeUser)(nil).CloseConnection), arg0) } -// GetAddressID mocks base method +// GetAddressID mocks base method. func (m *MockBridgeUser) GetAddressID(arg0 string) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAddressID", arg0) @@ -103,13 +103,13 @@ func (m *MockBridgeUser) GetAddressID(arg0 string) (string, error) { return ret0, ret1 } -// GetAddressID indicates an expected call of GetAddressID +// GetAddressID indicates an expected call of GetAddressID. func (mr *MockBridgeUserMockRecorder) GetAddressID(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressID", reflect.TypeOf((*MockBridgeUser)(nil).GetAddressID), arg0) } -// GetClient mocks base method +// GetClient mocks base method. func (m *MockBridgeUser) GetClient() pmapi.Client { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetClient") @@ -117,13 +117,13 @@ func (m *MockBridgeUser) GetClient() pmapi.Client { return ret0 } -// GetClient indicates an expected call of GetClient +// GetClient indicates an expected call of GetClient. func (mr *MockBridgeUserMockRecorder) GetClient() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClient", reflect.TypeOf((*MockBridgeUser)(nil).GetClient)) } -// GetPrimaryAddress mocks base method +// GetPrimaryAddress mocks base method. func (m *MockBridgeUser) GetPrimaryAddress() string { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPrimaryAddress") @@ -131,13 +131,13 @@ func (m *MockBridgeUser) GetPrimaryAddress() string { return ret0 } -// GetPrimaryAddress indicates an expected call of GetPrimaryAddress +// GetPrimaryAddress indicates an expected call of GetPrimaryAddress. func (mr *MockBridgeUserMockRecorder) GetPrimaryAddress() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrimaryAddress", reflect.TypeOf((*MockBridgeUser)(nil).GetPrimaryAddress)) } -// GetStoreAddresses mocks base method +// GetStoreAddresses mocks base method. func (m *MockBridgeUser) GetStoreAddresses() []string { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStoreAddresses") @@ -145,13 +145,13 @@ func (m *MockBridgeUser) GetStoreAddresses() []string { return ret0 } -// GetStoreAddresses indicates an expected call of GetStoreAddresses +// GetStoreAddresses indicates an expected call of GetStoreAddresses. func (mr *MockBridgeUserMockRecorder) GetStoreAddresses() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoreAddresses", reflect.TypeOf((*MockBridgeUser)(nil).GetStoreAddresses)) } -// ID mocks base method +// ID mocks base method. func (m *MockBridgeUser) ID() string { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ID") @@ -159,13 +159,13 @@ func (m *MockBridgeUser) ID() string { return ret0 } -// ID indicates an expected call of ID +// ID indicates an expected call of ID. func (mr *MockBridgeUserMockRecorder) ID() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockBridgeUser)(nil).ID)) } -// IsCombinedAddressMode mocks base method +// IsCombinedAddressMode mocks base method. func (m *MockBridgeUser) IsCombinedAddressMode() bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsCombinedAddressMode") @@ -173,13 +173,13 @@ func (m *MockBridgeUser) IsCombinedAddressMode() bool { return ret0 } -// IsCombinedAddressMode indicates an expected call of IsCombinedAddressMode +// IsCombinedAddressMode indicates an expected call of IsCombinedAddressMode. func (mr *MockBridgeUserMockRecorder) IsCombinedAddressMode() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsCombinedAddressMode", reflect.TypeOf((*MockBridgeUser)(nil).IsCombinedAddressMode)) } -// IsConnected mocks base method +// IsConnected mocks base method. func (m *MockBridgeUser) IsConnected() bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsConnected") @@ -187,13 +187,13 @@ func (m *MockBridgeUser) IsConnected() bool { return ret0 } -// IsConnected indicates an expected call of IsConnected +// IsConnected indicates an expected call of IsConnected. func (mr *MockBridgeUserMockRecorder) IsConnected() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsConnected", reflect.TypeOf((*MockBridgeUser)(nil).IsConnected)) } -// Logout mocks base method +// Logout mocks base method. func (m *MockBridgeUser) Logout() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Logout") @@ -201,13 +201,13 @@ func (m *MockBridgeUser) Logout() error { return ret0 } -// Logout indicates an expected call of Logout +// Logout indicates an expected call of Logout. func (mr *MockBridgeUserMockRecorder) Logout() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Logout", reflect.TypeOf((*MockBridgeUser)(nil).Logout)) } -// UpdateUser mocks base method +// UpdateUser mocks base method. func (m *MockBridgeUser) UpdateUser(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateUser", arg0) @@ -215,36 +215,36 @@ func (m *MockBridgeUser) UpdateUser(arg0 context.Context) error { return ret0 } -// UpdateUser indicates an expected call of UpdateUser +// UpdateUser indicates an expected call of UpdateUser. func (mr *MockBridgeUserMockRecorder) UpdateUser(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockBridgeUser)(nil).UpdateUser), arg0) } -// MockChangeNotifier is a mock of ChangeNotifier interface +// MockChangeNotifier is a mock of ChangeNotifier interface. type MockChangeNotifier struct { ctrl *gomock.Controller recorder *MockChangeNotifierMockRecorder } -// MockChangeNotifierMockRecorder is the mock recorder for MockChangeNotifier +// MockChangeNotifierMockRecorder is the mock recorder for MockChangeNotifier. type MockChangeNotifierMockRecorder struct { mock *MockChangeNotifier } -// NewMockChangeNotifier creates a new mock instance +// NewMockChangeNotifier creates a new mock instance. func NewMockChangeNotifier(ctrl *gomock.Controller) *MockChangeNotifier { mock := &MockChangeNotifier{ctrl: ctrl} mock.recorder = &MockChangeNotifierMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockChangeNotifier) EXPECT() *MockChangeNotifierMockRecorder { return m.recorder } -// CanDelete mocks base method +// CanDelete mocks base method. func (m *MockChangeNotifier) CanDelete(arg0 string) (bool, func()) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CanDelete", arg0) @@ -253,67 +253,67 @@ func (m *MockChangeNotifier) CanDelete(arg0 string) (bool, func()) { return ret0, ret1 } -// CanDelete indicates an expected call of CanDelete +// CanDelete indicates an expected call of CanDelete. func (mr *MockChangeNotifierMockRecorder) CanDelete(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanDelete", reflect.TypeOf((*MockChangeNotifier)(nil).CanDelete), arg0) } -// DeleteMessage mocks base method +// DeleteMessage mocks base method. func (m *MockChangeNotifier) DeleteMessage(arg0, arg1 string, arg2 uint32) { m.ctrl.T.Helper() m.ctrl.Call(m, "DeleteMessage", arg0, arg1, arg2) } -// DeleteMessage indicates an expected call of DeleteMessage +// DeleteMessage indicates an expected call of DeleteMessage. func (mr *MockChangeNotifierMockRecorder) DeleteMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMessage", reflect.TypeOf((*MockChangeNotifier)(nil).DeleteMessage), arg0, arg1, arg2) } -// MailboxCreated mocks base method +// MailboxCreated mocks base method. func (m *MockChangeNotifier) MailboxCreated(arg0, arg1 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "MailboxCreated", arg0, arg1) } -// MailboxCreated indicates an expected call of MailboxCreated +// MailboxCreated indicates an expected call of MailboxCreated. func (mr *MockChangeNotifierMockRecorder) MailboxCreated(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MailboxCreated", reflect.TypeOf((*MockChangeNotifier)(nil).MailboxCreated), arg0, arg1) } -// MailboxStatus mocks base method +// MailboxStatus mocks base method. func (m *MockChangeNotifier) MailboxStatus(arg0, arg1 string, arg2, arg3, arg4 uint32) { m.ctrl.T.Helper() m.ctrl.Call(m, "MailboxStatus", arg0, arg1, arg2, arg3, arg4) } -// MailboxStatus indicates an expected call of MailboxStatus +// MailboxStatus indicates an expected call of MailboxStatus. func (mr *MockChangeNotifierMockRecorder) MailboxStatus(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MailboxStatus", reflect.TypeOf((*MockChangeNotifier)(nil).MailboxStatus), arg0, arg1, arg2, arg3, arg4) } -// Notice mocks base method +// Notice mocks base method. func (m *MockChangeNotifier) Notice(arg0, arg1 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "Notice", arg0, arg1) } -// Notice indicates an expected call of Notice +// Notice indicates an expected call of Notice. func (mr *MockChangeNotifierMockRecorder) Notice(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notice", reflect.TypeOf((*MockChangeNotifier)(nil).Notice), arg0, arg1) } -// UpdateMessage mocks base method +// UpdateMessage mocks base method. func (m *MockChangeNotifier) UpdateMessage(arg0, arg1 string, arg2, arg3 uint32, arg4 *pmapi.Message, arg5 bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "UpdateMessage", arg0, arg1, arg2, arg3, arg4, arg5) } -// UpdateMessage indicates an expected call of UpdateMessage +// UpdateMessage indicates an expected call of UpdateMessage. func (mr *MockChangeNotifierMockRecorder) UpdateMessage(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMessage", reflect.TypeOf((*MockChangeNotifier)(nil).UpdateMessage), arg0, arg1, arg2, arg3, arg4, arg5) diff --git a/internal/store/mocks/utils_mocks.go b/internal/store/mocks/utils_mocks.go index 8a6c8677..ec99aa03 100644 --- a/internal/store/mocks/utils_mocks.go +++ b/internal/store/mocks/utils_mocks.go @@ -11,54 +11,54 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockListener is a mock of Listener interface +// MockListener is a mock of Listener interface. type MockListener struct { ctrl *gomock.Controller recorder *MockListenerMockRecorder } -// MockListenerMockRecorder is the mock recorder for MockListener +// MockListenerMockRecorder is the mock recorder for MockListener. type MockListenerMockRecorder struct { mock *MockListener } -// NewMockListener creates a new mock instance +// NewMockListener creates a new mock instance. func NewMockListener(ctrl *gomock.Controller) *MockListener { mock := &MockListener{ctrl: ctrl} mock.recorder = &MockListenerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockListener) EXPECT() *MockListenerMockRecorder { return m.recorder } -// Add mocks base method +// Add mocks base method. func (m *MockListener) Add(arg0 string, arg1 chan<- string) { m.ctrl.T.Helper() m.ctrl.Call(m, "Add", arg0, arg1) } -// Add indicates an expected call of Add +// Add indicates an expected call of Add. func (mr *MockListenerMockRecorder) Add(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockListener)(nil).Add), arg0, arg1) } -// Emit mocks base method +// Emit mocks base method. func (m *MockListener) Emit(arg0, arg1 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "Emit", arg0, arg1) } -// Emit indicates an expected call of Emit +// Emit indicates an expected call of Emit. func (mr *MockListenerMockRecorder) Emit(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Emit", reflect.TypeOf((*MockListener)(nil).Emit), arg0, arg1) } -// ProvideChannel mocks base method +// ProvideChannel mocks base method. func (m *MockListener) ProvideChannel(arg0 string) <-chan string { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ProvideChannel", arg0) @@ -66,55 +66,55 @@ func (m *MockListener) ProvideChannel(arg0 string) <-chan string { return ret0 } -// ProvideChannel indicates an expected call of ProvideChannel +// ProvideChannel indicates an expected call of ProvideChannel. func (mr *MockListenerMockRecorder) ProvideChannel(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvideChannel", reflect.TypeOf((*MockListener)(nil).ProvideChannel), arg0) } -// Remove mocks base method +// Remove mocks base method. func (m *MockListener) Remove(arg0 string, arg1 chan<- string) { m.ctrl.T.Helper() m.ctrl.Call(m, "Remove", arg0, arg1) } -// Remove indicates an expected call of Remove +// Remove indicates an expected call of Remove. func (mr *MockListenerMockRecorder) Remove(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockListener)(nil).Remove), arg0, arg1) } -// RetryEmit mocks base method +// RetryEmit mocks base method. func (m *MockListener) RetryEmit(arg0 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "RetryEmit", arg0) } -// RetryEmit indicates an expected call of RetryEmit +// RetryEmit indicates an expected call of RetryEmit. func (mr *MockListenerMockRecorder) RetryEmit(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetryEmit", reflect.TypeOf((*MockListener)(nil).RetryEmit), arg0) } -// SetBuffer mocks base method +// SetBuffer mocks base method. func (m *MockListener) SetBuffer(arg0 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetBuffer", arg0) } -// SetBuffer indicates an expected call of SetBuffer +// SetBuffer indicates an expected call of SetBuffer. func (mr *MockListenerMockRecorder) SetBuffer(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBuffer", reflect.TypeOf((*MockListener)(nil).SetBuffer), arg0) } -// SetLimit mocks base method +// SetLimit mocks base method. func (m *MockListener) SetLimit(arg0 string, arg1 time.Duration) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetLimit", arg0, arg1) } -// SetLimit indicates an expected call of SetLimit +// SetLimit indicates an expected call of SetLimit. func (mr *MockListenerMockRecorder) SetLimit(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLimit", reflect.TypeOf((*MockListener)(nil).SetLimit), arg0, arg1) diff --git a/internal/transfer/mocks/mocks.go b/internal/transfer/mocks/mocks.go index 1c8040e0..3b57b51d 100644 --- a/internal/transfer/mocks/mocks.go +++ b/internal/transfer/mocks/mocks.go @@ -12,65 +12,65 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockPanicHandler is a mock of PanicHandler interface +// MockPanicHandler is a mock of PanicHandler interface. type MockPanicHandler struct { ctrl *gomock.Controller recorder *MockPanicHandlerMockRecorder } -// MockPanicHandlerMockRecorder is the mock recorder for MockPanicHandler +// MockPanicHandlerMockRecorder is the mock recorder for MockPanicHandler. type MockPanicHandlerMockRecorder struct { mock *MockPanicHandler } -// NewMockPanicHandler creates a new mock instance +// NewMockPanicHandler creates a new mock instance. func NewMockPanicHandler(ctrl *gomock.Controller) *MockPanicHandler { mock := &MockPanicHandler{ctrl: ctrl} mock.recorder = &MockPanicHandlerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockPanicHandler) EXPECT() *MockPanicHandlerMockRecorder { return m.recorder } -// HandlePanic mocks base method +// HandlePanic mocks base method. func (m *MockPanicHandler) HandlePanic() { m.ctrl.T.Helper() m.ctrl.Call(m, "HandlePanic") } -// HandlePanic indicates an expected call of HandlePanic +// HandlePanic indicates an expected call of HandlePanic. func (mr *MockPanicHandlerMockRecorder) HandlePanic() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandlePanic", reflect.TypeOf((*MockPanicHandler)(nil).HandlePanic)) } -// MockIMAPClientProvider is a mock of IMAPClientProvider interface +// MockIMAPClientProvider is a mock of IMAPClientProvider interface. type MockIMAPClientProvider struct { ctrl *gomock.Controller recorder *MockIMAPClientProviderMockRecorder } -// MockIMAPClientProviderMockRecorder is the mock recorder for MockIMAPClientProvider +// MockIMAPClientProviderMockRecorder is the mock recorder for MockIMAPClientProvider. type MockIMAPClientProviderMockRecorder struct { mock *MockIMAPClientProvider } -// NewMockIMAPClientProvider creates a new mock instance +// NewMockIMAPClientProvider creates a new mock instance. func NewMockIMAPClientProvider(ctrl *gomock.Controller) *MockIMAPClientProvider { mock := &MockIMAPClientProvider{ctrl: ctrl} mock.recorder = &MockIMAPClientProviderMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockIMAPClientProvider) EXPECT() *MockIMAPClientProviderMockRecorder { return m.recorder } -// Authenticate mocks base method +// Authenticate mocks base method. func (m *MockIMAPClientProvider) Authenticate(arg0 sasl.Client) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Authenticate", arg0) @@ -78,13 +78,13 @@ func (m *MockIMAPClientProvider) Authenticate(arg0 sasl.Client) error { return ret0 } -// Authenticate indicates an expected call of Authenticate +// Authenticate indicates an expected call of Authenticate. func (mr *MockIMAPClientProviderMockRecorder) Authenticate(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Authenticate", reflect.TypeOf((*MockIMAPClientProvider)(nil).Authenticate), arg0) } -// Capability mocks base method +// Capability mocks base method. func (m *MockIMAPClientProvider) Capability() (map[string]bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Capability") @@ -93,13 +93,13 @@ func (m *MockIMAPClientProvider) Capability() (map[string]bool, error) { return ret0, ret1 } -// Capability indicates an expected call of Capability +// Capability indicates an expected call of Capability. func (mr *MockIMAPClientProviderMockRecorder) Capability() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Capability", reflect.TypeOf((*MockIMAPClientProvider)(nil).Capability)) } -// Fetch mocks base method +// Fetch mocks base method. func (m *MockIMAPClientProvider) Fetch(arg0 *imap.SeqSet, arg1 []imap.FetchItem, arg2 chan *imap.Message) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Fetch", arg0, arg1, arg2) @@ -107,13 +107,13 @@ func (m *MockIMAPClientProvider) Fetch(arg0 *imap.SeqSet, arg1 []imap.FetchItem, return ret0 } -// Fetch indicates an expected call of Fetch +// Fetch indicates an expected call of Fetch. func (mr *MockIMAPClientProviderMockRecorder) Fetch(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Fetch", reflect.TypeOf((*MockIMAPClientProvider)(nil).Fetch), arg0, arg1, arg2) } -// List mocks base method +// List mocks base method. func (m *MockIMAPClientProvider) List(arg0, arg1 string, arg2 chan *imap.MailboxInfo) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "List", arg0, arg1, arg2) @@ -121,13 +121,13 @@ func (m *MockIMAPClientProvider) List(arg0, arg1 string, arg2 chan *imap.Mailbox return ret0 } -// List indicates an expected call of List +// List indicates an expected call of List. func (mr *MockIMAPClientProviderMockRecorder) List(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIMAPClientProvider)(nil).List), arg0, arg1, arg2) } -// Login mocks base method +// Login mocks base method. func (m *MockIMAPClientProvider) Login(arg0, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Login", arg0, arg1) @@ -135,13 +135,13 @@ func (m *MockIMAPClientProvider) Login(arg0, arg1 string) error { return ret0 } -// Login indicates an expected call of Login +// Login indicates an expected call of Login. func (mr *MockIMAPClientProviderMockRecorder) Login(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Login", reflect.TypeOf((*MockIMAPClientProvider)(nil).Login), arg0, arg1) } -// Select mocks base method +// Select mocks base method. func (m *MockIMAPClientProvider) Select(arg0 string, arg1 bool) (*imap.MailboxStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Select", arg0, arg1) @@ -150,13 +150,13 @@ func (m *MockIMAPClientProvider) Select(arg0 string, arg1 bool) (*imap.MailboxSt return ret0, ret1 } -// Select indicates an expected call of Select +// Select indicates an expected call of Select. func (mr *MockIMAPClientProviderMockRecorder) Select(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Select", reflect.TypeOf((*MockIMAPClientProvider)(nil).Select), arg0, arg1) } -// State mocks base method +// State mocks base method. func (m *MockIMAPClientProvider) State() imap.ConnState { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "State") @@ -164,13 +164,13 @@ func (m *MockIMAPClientProvider) State() imap.ConnState { return ret0 } -// State indicates an expected call of State +// State indicates an expected call of State. func (mr *MockIMAPClientProviderMockRecorder) State() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "State", reflect.TypeOf((*MockIMAPClientProvider)(nil).State)) } -// Support mocks base method +// Support mocks base method. func (m *MockIMAPClientProvider) Support(arg0 string) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Support", arg0) @@ -179,13 +179,13 @@ func (m *MockIMAPClientProvider) Support(arg0 string) (bool, error) { return ret0, ret1 } -// Support indicates an expected call of Support +// Support indicates an expected call of Support. func (mr *MockIMAPClientProviderMockRecorder) Support(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Support", reflect.TypeOf((*MockIMAPClientProvider)(nil).Support), arg0) } -// SupportAuth mocks base method +// SupportAuth mocks base method. func (m *MockIMAPClientProvider) SupportAuth(arg0 string) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SupportAuth", arg0) @@ -194,13 +194,13 @@ func (m *MockIMAPClientProvider) SupportAuth(arg0 string) (bool, error) { return ret0, ret1 } -// SupportAuth indicates an expected call of SupportAuth +// SupportAuth indicates an expected call of SupportAuth. func (mr *MockIMAPClientProviderMockRecorder) SupportAuth(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SupportAuth", reflect.TypeOf((*MockIMAPClientProvider)(nil).SupportAuth), arg0) } -// UidFetch mocks base method +// UidFetch mocks base method. func (m *MockIMAPClientProvider) UidFetch(arg0 *imap.SeqSet, arg1 []imap.FetchItem, arg2 chan *imap.Message) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UidFetch", arg0, arg1, arg2) @@ -208,7 +208,7 @@ func (m *MockIMAPClientProvider) UidFetch(arg0 *imap.SeqSet, arg1 []imap.FetchIt return ret0 } -// UidFetch indicates an expected call of UidFetch +// UidFetch indicates an expected call of UidFetch. func (mr *MockIMAPClientProviderMockRecorder) UidFetch(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UidFetch", reflect.TypeOf((*MockIMAPClientProvider)(nil).UidFetch), arg0, arg1, arg2) diff --git a/internal/users/mocks/listener_mocks.go b/internal/users/mocks/listener_mocks.go index 8a6c8677..ec99aa03 100644 --- a/internal/users/mocks/listener_mocks.go +++ b/internal/users/mocks/listener_mocks.go @@ -11,54 +11,54 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockListener is a mock of Listener interface +// MockListener is a mock of Listener interface. type MockListener struct { ctrl *gomock.Controller recorder *MockListenerMockRecorder } -// MockListenerMockRecorder is the mock recorder for MockListener +// MockListenerMockRecorder is the mock recorder for MockListener. type MockListenerMockRecorder struct { mock *MockListener } -// NewMockListener creates a new mock instance +// NewMockListener creates a new mock instance. func NewMockListener(ctrl *gomock.Controller) *MockListener { mock := &MockListener{ctrl: ctrl} mock.recorder = &MockListenerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockListener) EXPECT() *MockListenerMockRecorder { return m.recorder } -// Add mocks base method +// Add mocks base method. func (m *MockListener) Add(arg0 string, arg1 chan<- string) { m.ctrl.T.Helper() m.ctrl.Call(m, "Add", arg0, arg1) } -// Add indicates an expected call of Add +// Add indicates an expected call of Add. func (mr *MockListenerMockRecorder) Add(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockListener)(nil).Add), arg0, arg1) } -// Emit mocks base method +// Emit mocks base method. func (m *MockListener) Emit(arg0, arg1 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "Emit", arg0, arg1) } -// Emit indicates an expected call of Emit +// Emit indicates an expected call of Emit. func (mr *MockListenerMockRecorder) Emit(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Emit", reflect.TypeOf((*MockListener)(nil).Emit), arg0, arg1) } -// ProvideChannel mocks base method +// ProvideChannel mocks base method. func (m *MockListener) ProvideChannel(arg0 string) <-chan string { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ProvideChannel", arg0) @@ -66,55 +66,55 @@ func (m *MockListener) ProvideChannel(arg0 string) <-chan string { return ret0 } -// ProvideChannel indicates an expected call of ProvideChannel +// ProvideChannel indicates an expected call of ProvideChannel. func (mr *MockListenerMockRecorder) ProvideChannel(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvideChannel", reflect.TypeOf((*MockListener)(nil).ProvideChannel), arg0) } -// Remove mocks base method +// Remove mocks base method. func (m *MockListener) Remove(arg0 string, arg1 chan<- string) { m.ctrl.T.Helper() m.ctrl.Call(m, "Remove", arg0, arg1) } -// Remove indicates an expected call of Remove +// Remove indicates an expected call of Remove. func (mr *MockListenerMockRecorder) Remove(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockListener)(nil).Remove), arg0, arg1) } -// RetryEmit mocks base method +// RetryEmit mocks base method. func (m *MockListener) RetryEmit(arg0 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "RetryEmit", arg0) } -// RetryEmit indicates an expected call of RetryEmit +// RetryEmit indicates an expected call of RetryEmit. func (mr *MockListenerMockRecorder) RetryEmit(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetryEmit", reflect.TypeOf((*MockListener)(nil).RetryEmit), arg0) } -// SetBuffer mocks base method +// SetBuffer mocks base method. func (m *MockListener) SetBuffer(arg0 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetBuffer", arg0) } -// SetBuffer indicates an expected call of SetBuffer +// SetBuffer indicates an expected call of SetBuffer. func (mr *MockListenerMockRecorder) SetBuffer(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBuffer", reflect.TypeOf((*MockListener)(nil).SetBuffer), arg0) } -// SetLimit mocks base method +// SetLimit mocks base method. func (m *MockListener) SetLimit(arg0 string, arg1 time.Duration) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetLimit", arg0, arg1) } -// SetLimit indicates an expected call of SetLimit +// SetLimit indicates an expected call of SetLimit. func (mr *MockListenerMockRecorder) SetLimit(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLimit", reflect.TypeOf((*MockListener)(nil).SetLimit), arg0, arg1) diff --git a/internal/users/mocks/mocks.go b/internal/users/mocks/mocks.go index 8293f297..83e327dd 100644 --- a/internal/users/mocks/mocks.go +++ b/internal/users/mocks/mocks.go @@ -12,30 +12,30 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockLocator is a mock of Locator interface +// MockLocator is a mock of Locator interface. type MockLocator struct { ctrl *gomock.Controller recorder *MockLocatorMockRecorder } -// MockLocatorMockRecorder is the mock recorder for MockLocator +// MockLocatorMockRecorder is the mock recorder for MockLocator. type MockLocatorMockRecorder struct { mock *MockLocator } -// NewMockLocator creates a new mock instance +// NewMockLocator creates a new mock instance. func NewMockLocator(ctrl *gomock.Controller) *MockLocator { mock := &MockLocator{ctrl: ctrl} mock.recorder = &MockLocatorMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockLocator) EXPECT() *MockLocatorMockRecorder { return m.recorder } -// Clear mocks base method +// Clear mocks base method. func (m *MockLocator) Clear() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Clear") @@ -43,71 +43,71 @@ func (m *MockLocator) Clear() error { return ret0 } -// Clear indicates an expected call of Clear +// Clear indicates an expected call of Clear. func (mr *MockLocatorMockRecorder) Clear() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockLocator)(nil).Clear)) } -// MockPanicHandler is a mock of PanicHandler interface +// MockPanicHandler is a mock of PanicHandler interface. type MockPanicHandler struct { ctrl *gomock.Controller recorder *MockPanicHandlerMockRecorder } -// MockPanicHandlerMockRecorder is the mock recorder for MockPanicHandler +// MockPanicHandlerMockRecorder is the mock recorder for MockPanicHandler. type MockPanicHandlerMockRecorder struct { mock *MockPanicHandler } -// NewMockPanicHandler creates a new mock instance +// NewMockPanicHandler creates a new mock instance. func NewMockPanicHandler(ctrl *gomock.Controller) *MockPanicHandler { mock := &MockPanicHandler{ctrl: ctrl} mock.recorder = &MockPanicHandlerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockPanicHandler) EXPECT() *MockPanicHandlerMockRecorder { return m.recorder } -// HandlePanic mocks base method +// HandlePanic mocks base method. func (m *MockPanicHandler) HandlePanic() { m.ctrl.T.Helper() m.ctrl.Call(m, "HandlePanic") } -// HandlePanic indicates an expected call of HandlePanic +// HandlePanic indicates an expected call of HandlePanic. func (mr *MockPanicHandlerMockRecorder) HandlePanic() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandlePanic", reflect.TypeOf((*MockPanicHandler)(nil).HandlePanic)) } -// MockCredentialsStorer is a mock of CredentialsStorer interface +// MockCredentialsStorer is a mock of CredentialsStorer interface. type MockCredentialsStorer struct { ctrl *gomock.Controller recorder *MockCredentialsStorerMockRecorder } -// MockCredentialsStorerMockRecorder is the mock recorder for MockCredentialsStorer +// MockCredentialsStorerMockRecorder is the mock recorder for MockCredentialsStorer. type MockCredentialsStorerMockRecorder struct { mock *MockCredentialsStorer } -// NewMockCredentialsStorer creates a new mock instance +// NewMockCredentialsStorer creates a new mock instance. func NewMockCredentialsStorer(ctrl *gomock.Controller) *MockCredentialsStorer { mock := &MockCredentialsStorer{ctrl: ctrl} mock.recorder = &MockCredentialsStorerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockCredentialsStorer) EXPECT() *MockCredentialsStorerMockRecorder { return m.recorder } -// Add mocks base method +// Add mocks base method. func (m *MockCredentialsStorer) Add(arg0, arg1, arg2, arg3 string, arg4 []byte, arg5 []string) (*credentials.Credentials, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Add", arg0, arg1, arg2, arg3, arg4, arg5) @@ -116,13 +116,13 @@ func (m *MockCredentialsStorer) Add(arg0, arg1, arg2, arg3 string, arg4 []byte, return ret0, ret1 } -// Add indicates an expected call of Add +// Add indicates an expected call of Add. func (mr *MockCredentialsStorerMockRecorder) Add(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockCredentialsStorer)(nil).Add), arg0, arg1, arg2, arg3, arg4, arg5) } -// Delete mocks base method +// Delete mocks base method. func (m *MockCredentialsStorer) Delete(arg0 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Delete", arg0) @@ -130,13 +130,13 @@ func (m *MockCredentialsStorer) Delete(arg0 string) error { return ret0 } -// Delete indicates an expected call of Delete +// Delete indicates an expected call of Delete. func (mr *MockCredentialsStorerMockRecorder) Delete(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockCredentialsStorer)(nil).Delete), arg0) } -// Get mocks base method +// Get mocks base method. func (m *MockCredentialsStorer) Get(arg0 string) (*credentials.Credentials, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", arg0) @@ -145,13 +145,13 @@ func (m *MockCredentialsStorer) Get(arg0 string) (*credentials.Credentials, erro return ret0, ret1 } -// Get indicates an expected call of Get +// Get indicates an expected call of Get. func (mr *MockCredentialsStorerMockRecorder) Get(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockCredentialsStorer)(nil).Get), arg0) } -// List mocks base method +// List mocks base method. func (m *MockCredentialsStorer) List() ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "List") @@ -160,13 +160,13 @@ func (m *MockCredentialsStorer) List() ([]string, error) { return ret0, ret1 } -// List indicates an expected call of List +// List indicates an expected call of List. func (mr *MockCredentialsStorerMockRecorder) List() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockCredentialsStorer)(nil).List)) } -// Logout mocks base method +// Logout mocks base method. func (m *MockCredentialsStorer) Logout(arg0 string) (*credentials.Credentials, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Logout", arg0) @@ -175,13 +175,13 @@ func (m *MockCredentialsStorer) Logout(arg0 string) (*credentials.Credentials, e return ret0, ret1 } -// Logout indicates an expected call of Logout +// Logout indicates an expected call of Logout. func (mr *MockCredentialsStorerMockRecorder) Logout(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Logout", reflect.TypeOf((*MockCredentialsStorer)(nil).Logout), arg0) } -// SwitchAddressMode mocks base method +// SwitchAddressMode mocks base method. func (m *MockCredentialsStorer) SwitchAddressMode(arg0 string) (*credentials.Credentials, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SwitchAddressMode", arg0) @@ -190,13 +190,13 @@ func (m *MockCredentialsStorer) SwitchAddressMode(arg0 string) (*credentials.Cre return ret0, ret1 } -// SwitchAddressMode indicates an expected call of SwitchAddressMode +// SwitchAddressMode indicates an expected call of SwitchAddressMode. func (mr *MockCredentialsStorerMockRecorder) SwitchAddressMode(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwitchAddressMode", reflect.TypeOf((*MockCredentialsStorer)(nil).SwitchAddressMode), arg0) } -// UpdateEmails mocks base method +// UpdateEmails mocks base method. func (m *MockCredentialsStorer) UpdateEmails(arg0 string, arg1 []string) (*credentials.Credentials, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateEmails", arg0, arg1) @@ -205,13 +205,13 @@ func (m *MockCredentialsStorer) UpdateEmails(arg0 string, arg1 []string) (*crede return ret0, ret1 } -// UpdateEmails indicates an expected call of UpdateEmails +// UpdateEmails indicates an expected call of UpdateEmails. func (mr *MockCredentialsStorerMockRecorder) UpdateEmails(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEmails", reflect.TypeOf((*MockCredentialsStorer)(nil).UpdateEmails), arg0, arg1) } -// UpdatePassword mocks base method +// UpdatePassword mocks base method. func (m *MockCredentialsStorer) UpdatePassword(arg0 string, arg1 []byte) (*credentials.Credentials, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdatePassword", arg0, arg1) @@ -220,13 +220,13 @@ func (m *MockCredentialsStorer) UpdatePassword(arg0 string, arg1 []byte) (*crede return ret0, ret1 } -// UpdatePassword indicates an expected call of UpdatePassword +// UpdatePassword indicates an expected call of UpdatePassword. func (mr *MockCredentialsStorerMockRecorder) UpdatePassword(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePassword", reflect.TypeOf((*MockCredentialsStorer)(nil).UpdatePassword), arg0, arg1) } -// UpdateToken mocks base method +// UpdateToken mocks base method. func (m *MockCredentialsStorer) UpdateToken(arg0, arg1, arg2 string) (*credentials.Credentials, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateToken", arg0, arg1, arg2) @@ -235,36 +235,36 @@ func (m *MockCredentialsStorer) UpdateToken(arg0, arg1, arg2 string) (*credentia return ret0, ret1 } -// UpdateToken indicates an expected call of UpdateToken +// UpdateToken indicates an expected call of UpdateToken. func (mr *MockCredentialsStorerMockRecorder) UpdateToken(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateToken", reflect.TypeOf((*MockCredentialsStorer)(nil).UpdateToken), arg0, arg1, arg2) } -// MockStoreMaker is a mock of StoreMaker interface +// MockStoreMaker is a mock of StoreMaker interface. type MockStoreMaker struct { ctrl *gomock.Controller recorder *MockStoreMakerMockRecorder } -// MockStoreMakerMockRecorder is the mock recorder for MockStoreMaker +// MockStoreMakerMockRecorder is the mock recorder for MockStoreMaker. type MockStoreMakerMockRecorder struct { mock *MockStoreMaker } -// NewMockStoreMaker creates a new mock instance +// NewMockStoreMaker creates a new mock instance. func NewMockStoreMaker(ctrl *gomock.Controller) *MockStoreMaker { mock := &MockStoreMaker{ctrl: ctrl} mock.recorder = &MockStoreMakerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockStoreMaker) EXPECT() *MockStoreMakerMockRecorder { return m.recorder } -// New mocks base method +// New mocks base method. func (m *MockStoreMaker) New(arg0 store.BridgeUser) (*store.Store, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "New", arg0) @@ -273,13 +273,13 @@ func (m *MockStoreMaker) New(arg0 store.BridgeUser) (*store.Store, error) { return ret0, ret1 } -// New indicates an expected call of New +// New indicates an expected call of New. func (mr *MockStoreMakerMockRecorder) New(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "New", reflect.TypeOf((*MockStoreMaker)(nil).New), arg0) } -// Remove mocks base method +// Remove mocks base method. func (m *MockStoreMaker) Remove(arg0 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Remove", arg0) @@ -287,7 +287,7 @@ func (m *MockStoreMaker) Remove(arg0 string) error { return ret0 } -// Remove indicates an expected call of Remove +// Remove indicates an expected call of Remove. func (mr *MockStoreMakerMockRecorder) Remove(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockStoreMaker)(nil).Remove), arg0) diff --git a/pkg/message/mocks/mocks.go b/pkg/message/mocks/mocks.go index 0aa4b7ed..4c58525d 100644 --- a/pkg/message/mocks/mocks.go +++ b/pkg/message/mocks/mocks.go @@ -14,30 +14,30 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockFetcher is a mock of Fetcher interface +// MockFetcher is a mock of Fetcher interface. type MockFetcher struct { ctrl *gomock.Controller recorder *MockFetcherMockRecorder } -// MockFetcherMockRecorder is the mock recorder for MockFetcher +// MockFetcherMockRecorder is the mock recorder for MockFetcher. type MockFetcherMockRecorder struct { mock *MockFetcher } -// NewMockFetcher creates a new mock instance +// NewMockFetcher creates a new mock instance. func NewMockFetcher(ctrl *gomock.Controller) *MockFetcher { mock := &MockFetcher{ctrl: ctrl} mock.recorder = &MockFetcherMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockFetcher) EXPECT() *MockFetcherMockRecorder { return m.recorder } -// GetAttachment mocks base method +// GetAttachment mocks base method. func (m *MockFetcher) GetAttachment(arg0 context.Context, arg1 string) (io.ReadCloser, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAttachment", arg0, arg1) @@ -46,13 +46,13 @@ func (m *MockFetcher) GetAttachment(arg0 context.Context, arg1 string) (io.ReadC return ret0, ret1 } -// GetAttachment indicates an expected call of GetAttachment +// GetAttachment indicates an expected call of GetAttachment. func (mr *MockFetcherMockRecorder) GetAttachment(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAttachment", reflect.TypeOf((*MockFetcher)(nil).GetAttachment), arg0, arg1) } -// GetMessage mocks base method +// GetMessage mocks base method. func (m *MockFetcher) GetMessage(arg0 context.Context, arg1 string) (*pmapi.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetMessage", arg0, arg1) @@ -61,13 +61,13 @@ func (m *MockFetcher) GetMessage(arg0 context.Context, arg1 string) (*pmapi.Mess return ret0, ret1 } -// GetMessage indicates an expected call of GetMessage +// GetMessage indicates an expected call of GetMessage. func (mr *MockFetcherMockRecorder) GetMessage(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessage", reflect.TypeOf((*MockFetcher)(nil).GetMessage), arg0, arg1) } -// KeyRingForAddressID mocks base method +// KeyRingForAddressID mocks base method. func (m *MockFetcher) KeyRingForAddressID(arg0 string) (*crypto.KeyRing, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "KeyRingForAddressID", arg0) @@ -76,7 +76,7 @@ func (m *MockFetcher) KeyRingForAddressID(arg0 string) (*crypto.KeyRing, error) return ret0, ret1 } -// KeyRingForAddressID indicates an expected call of KeyRingForAddressID +// KeyRingForAddressID indicates an expected call of KeyRingForAddressID. func (mr *MockFetcherMockRecorder) KeyRingForAddressID(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KeyRingForAddressID", reflect.TypeOf((*MockFetcher)(nil).KeyRingForAddressID), arg0) diff --git a/pkg/pmapi/client_types.go b/pkg/pmapi/client_types.go index 73f072e1..bf87bd60 100644 --- a/pkg/pmapi/client_types.go +++ b/pkg/pmapi/client_types.go @@ -73,8 +73,6 @@ type Client interface { KeyRingForAddressID(string) (kr *crypto.KeyRing, err error) GetPublicKeysForEmail(context.Context, string) ([]PublicKey, bool, error) - - GetCurrentAuth() *Auth } type AuthRefreshHandler func(*AuthRefresh) diff --git a/pkg/pmapi/mocks/mocks.go b/pkg/pmapi/mocks/mocks.go index 1f46f6c8..03085507 100644 --- a/pkg/pmapi/mocks/mocks.go +++ b/pkg/pmapi/mocks/mocks.go @@ -17,42 +17,42 @@ import ( logrus "github.com/sirupsen/logrus" ) -// MockClient is a mock of Client interface +// MockClient is a mock of Client interface. type MockClient struct { ctrl *gomock.Controller recorder *MockClientMockRecorder } -// MockClientMockRecorder is the mock recorder for MockClient +// MockClientMockRecorder is the mock recorder for MockClient. type MockClientMockRecorder struct { mock *MockClient } -// NewMockClient creates a new mock instance +// NewMockClient creates a new mock instance. func NewMockClient(ctrl *gomock.Controller) *MockClient { mock := &MockClient{ctrl: ctrl} mock.recorder = &MockClientMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockClient) EXPECT() *MockClientMockRecorder { return m.recorder } -// AddAuthRefreshHandler mocks base method +// AddAuthRefreshHandler mocks base method. func (m *MockClient) AddAuthRefreshHandler(arg0 pmapi.AuthRefreshHandler) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddAuthRefreshHandler", arg0) } -// AddAuthRefreshHandler indicates an expected call of AddAuthRefreshHandler +// AddAuthRefreshHandler indicates an expected call of AddAuthRefreshHandler. func (mr *MockClientMockRecorder) AddAuthRefreshHandler(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAuthRefreshHandler", reflect.TypeOf((*MockClient)(nil).AddAuthRefreshHandler), arg0) } -// Addresses mocks base method +// Addresses mocks base method. func (m *MockClient) Addresses() pmapi.AddressList { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Addresses") @@ -60,13 +60,13 @@ func (m *MockClient) Addresses() pmapi.AddressList { return ret0 } -// Addresses indicates an expected call of Addresses +// Addresses indicates an expected call of Addresses. func (mr *MockClientMockRecorder) Addresses() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addresses", reflect.TypeOf((*MockClient)(nil).Addresses)) } -// Auth2FA mocks base method +// Auth2FA mocks base method. func (m *MockClient) Auth2FA(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Auth2FA", arg0, arg1) @@ -74,13 +74,13 @@ func (m *MockClient) Auth2FA(arg0 context.Context, arg1 string) error { return ret0 } -// Auth2FA indicates an expected call of Auth2FA +// Auth2FA indicates an expected call of Auth2FA. func (mr *MockClientMockRecorder) Auth2FA(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Auth2FA", reflect.TypeOf((*MockClient)(nil).Auth2FA), arg0, arg1) } -// AuthDelete mocks base method +// AuthDelete mocks base method. func (m *MockClient) AuthDelete(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AuthDelete", arg0) @@ -88,13 +88,13 @@ func (m *MockClient) AuthDelete(arg0 context.Context) error { return ret0 } -// AuthDelete indicates an expected call of AuthDelete +// AuthDelete indicates an expected call of AuthDelete. func (mr *MockClientMockRecorder) AuthDelete(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthDelete", reflect.TypeOf((*MockClient)(nil).AuthDelete), arg0) } -// AuthSalt mocks base method +// AuthSalt mocks base method. func (m *MockClient) AuthSalt(arg0 context.Context) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AuthSalt", arg0) @@ -103,13 +103,13 @@ func (m *MockClient) AuthSalt(arg0 context.Context) (string, error) { return ret0, ret1 } -// AuthSalt indicates an expected call of AuthSalt +// AuthSalt indicates an expected call of AuthSalt. func (mr *MockClientMockRecorder) AuthSalt(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthSalt", reflect.TypeOf((*MockClient)(nil).AuthSalt), arg0) } -// CountMessages mocks base method +// CountMessages mocks base method. func (m *MockClient) CountMessages(arg0 context.Context, arg1 string) ([]*pmapi.MessagesCount, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CountMessages", arg0, arg1) @@ -118,13 +118,13 @@ func (m *MockClient) CountMessages(arg0 context.Context, arg1 string) ([]*pmapi. return ret0, ret1 } -// CountMessages indicates an expected call of CountMessages +// CountMessages indicates an expected call of CountMessages. func (mr *MockClientMockRecorder) CountMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CountMessages", reflect.TypeOf((*MockClient)(nil).CountMessages), arg0, arg1) } -// CreateAttachment mocks base method +// CreateAttachment mocks base method. func (m *MockClient) CreateAttachment(arg0 context.Context, arg1 *pmapi.Attachment, arg2, arg3 io.Reader) (*pmapi.Attachment, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateAttachment", arg0, arg1, arg2, arg3) @@ -133,13 +133,13 @@ func (m *MockClient) CreateAttachment(arg0 context.Context, arg1 *pmapi.Attachme return ret0, ret1 } -// CreateAttachment indicates an expected call of CreateAttachment +// CreateAttachment indicates an expected call of CreateAttachment. func (mr *MockClientMockRecorder) CreateAttachment(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAttachment", reflect.TypeOf((*MockClient)(nil).CreateAttachment), arg0, arg1, arg2, arg3) } -// CreateDraft mocks base method +// CreateDraft mocks base method. func (m *MockClient) CreateDraft(arg0 context.Context, arg1 *pmapi.Message, arg2 string, arg3 int) (*pmapi.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateDraft", arg0, arg1, arg2, arg3) @@ -148,13 +148,13 @@ func (m *MockClient) CreateDraft(arg0 context.Context, arg1 *pmapi.Message, arg2 return ret0, ret1 } -// CreateDraft indicates an expected call of CreateDraft +// CreateDraft indicates an expected call of CreateDraft. func (mr *MockClientMockRecorder) CreateDraft(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDraft", reflect.TypeOf((*MockClient)(nil).CreateDraft), arg0, arg1, arg2, arg3) } -// CreateLabel mocks base method +// CreateLabel mocks base method. func (m *MockClient) CreateLabel(arg0 context.Context, arg1 *pmapi.Label) (*pmapi.Label, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateLabel", arg0, arg1) @@ -163,13 +163,13 @@ func (m *MockClient) CreateLabel(arg0 context.Context, arg1 *pmapi.Label) (*pmap return ret0, ret1 } -// CreateLabel indicates an expected call of CreateLabel +// CreateLabel indicates an expected call of CreateLabel. func (mr *MockClientMockRecorder) CreateLabel(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLabel", reflect.TypeOf((*MockClient)(nil).CreateLabel), arg0, arg1) } -// CurrentUser mocks base method +// CurrentUser mocks base method. func (m *MockClient) CurrentUser(arg0 context.Context) (*pmapi.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CurrentUser", arg0) @@ -178,13 +178,13 @@ func (m *MockClient) CurrentUser(arg0 context.Context) (*pmapi.User, error) { return ret0, ret1 } -// CurrentUser indicates an expected call of CurrentUser +// CurrentUser indicates an expected call of CurrentUser. func (mr *MockClientMockRecorder) CurrentUser(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentUser", reflect.TypeOf((*MockClient)(nil).CurrentUser), arg0) } -// DecryptAndVerifyCards mocks base method +// DecryptAndVerifyCards mocks base method. func (m *MockClient) DecryptAndVerifyCards(arg0 []pmapi.Card) ([]pmapi.Card, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DecryptAndVerifyCards", arg0) @@ -193,13 +193,13 @@ func (m *MockClient) DecryptAndVerifyCards(arg0 []pmapi.Card) ([]pmapi.Card, err return ret0, ret1 } -// DecryptAndVerifyCards indicates an expected call of DecryptAndVerifyCards +// DecryptAndVerifyCards indicates an expected call of DecryptAndVerifyCards. func (mr *MockClientMockRecorder) DecryptAndVerifyCards(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptAndVerifyCards", reflect.TypeOf((*MockClient)(nil).DecryptAndVerifyCards), arg0) } -// DeleteLabel mocks base method +// DeleteLabel mocks base method. func (m *MockClient) DeleteLabel(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DeleteLabel", arg0, arg1) @@ -207,13 +207,13 @@ func (m *MockClient) DeleteLabel(arg0 context.Context, arg1 string) error { return ret0 } -// DeleteLabel indicates an expected call of DeleteLabel +// DeleteLabel indicates an expected call of DeleteLabel. func (mr *MockClientMockRecorder) DeleteLabel(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteLabel", reflect.TypeOf((*MockClient)(nil).DeleteLabel), arg0, arg1) } -// DeleteMessages mocks base method +// DeleteMessages mocks base method. func (m *MockClient) DeleteMessages(arg0 context.Context, arg1 []string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DeleteMessages", arg0, arg1) @@ -221,13 +221,13 @@ func (m *MockClient) DeleteMessages(arg0 context.Context, arg1 []string) error { return ret0 } -// DeleteMessages indicates an expected call of DeleteMessages +// DeleteMessages indicates an expected call of DeleteMessages. func (mr *MockClientMockRecorder) DeleteMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMessages", reflect.TypeOf((*MockClient)(nil).DeleteMessages), arg0, arg1) } -// EmptyFolder mocks base method +// EmptyFolder mocks base method. func (m *MockClient) EmptyFolder(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "EmptyFolder", arg0, arg1, arg2) @@ -235,13 +235,13 @@ func (m *MockClient) EmptyFolder(arg0 context.Context, arg1, arg2 string) error return ret0 } -// EmptyFolder indicates an expected call of EmptyFolder +// EmptyFolder indicates an expected call of EmptyFolder. func (mr *MockClientMockRecorder) EmptyFolder(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmptyFolder", reflect.TypeOf((*MockClient)(nil).EmptyFolder), arg0, arg1, arg2) } -// GetAddresses mocks base method +// GetAddresses mocks base method. func (m *MockClient) GetAddresses(arg0 context.Context) (pmapi.AddressList, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAddresses", arg0) @@ -250,13 +250,13 @@ func (m *MockClient) GetAddresses(arg0 context.Context) (pmapi.AddressList, erro return ret0, ret1 } -// GetAddresses indicates an expected call of GetAddresses +// GetAddresses indicates an expected call of GetAddresses. func (mr *MockClientMockRecorder) GetAddresses(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddresses", reflect.TypeOf((*MockClient)(nil).GetAddresses), arg0) } -// GetAttachment mocks base method +// GetAttachment mocks base method. func (m *MockClient) GetAttachment(arg0 context.Context, arg1 string) (io.ReadCloser, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAttachment", arg0, arg1) @@ -265,13 +265,13 @@ func (m *MockClient) GetAttachment(arg0 context.Context, arg1 string) (io.ReadCl return ret0, ret1 } -// GetAttachment indicates an expected call of GetAttachment +// GetAttachment indicates an expected call of GetAttachment. func (mr *MockClientMockRecorder) GetAttachment(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAttachment", reflect.TypeOf((*MockClient)(nil).GetAttachment), arg0, arg1) } -// GetContactByID mocks base method +// GetContactByID mocks base method. func (m *MockClient) GetContactByID(arg0 context.Context, arg1 string) (pmapi.Contact, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetContactByID", arg0, arg1) @@ -280,13 +280,13 @@ func (m *MockClient) GetContactByID(arg0 context.Context, arg1 string) (pmapi.Co return ret0, ret1 } -// GetContactByID indicates an expected call of GetContactByID +// GetContactByID indicates an expected call of GetContactByID. func (mr *MockClientMockRecorder) GetContactByID(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContactByID", reflect.TypeOf((*MockClient)(nil).GetContactByID), arg0, arg1) } -// GetContactEmailByEmail mocks base method +// GetContactEmailByEmail mocks base method. func (m *MockClient) GetContactEmailByEmail(arg0 context.Context, arg1 string, arg2, arg3 int) ([]pmapi.ContactEmail, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetContactEmailByEmail", arg0, arg1, arg2, arg3) @@ -295,27 +295,13 @@ func (m *MockClient) GetContactEmailByEmail(arg0 context.Context, arg1 string, a return ret0, ret1 } -// GetContactEmailByEmail indicates an expected call of GetContactEmailByEmail +// GetContactEmailByEmail indicates an expected call of GetContactEmailByEmail. func (mr *MockClientMockRecorder) GetContactEmailByEmail(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContactEmailByEmail", reflect.TypeOf((*MockClient)(nil).GetContactEmailByEmail), arg0, arg1, arg2, arg3) } -// GetCurrentAuth mocks base method -func (m *MockClient) GetCurrentAuth() *pmapi.Auth { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentAuth") - ret0, _ := ret[0].(*pmapi.Auth) - return ret0 -} - -// GetCurrentAuth indicates an expected call of GetCurrentAuth -func (mr *MockClientMockRecorder) GetCurrentAuth() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentAuth", reflect.TypeOf((*MockClient)(nil).GetCurrentAuth)) -} - -// GetEvent mocks base method +// GetEvent mocks base method. func (m *MockClient) GetEvent(arg0 context.Context, arg1 string) (*pmapi.Event, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetEvent", arg0, arg1) @@ -324,13 +310,13 @@ func (m *MockClient) GetEvent(arg0 context.Context, arg1 string) (*pmapi.Event, return ret0, ret1 } -// GetEvent indicates an expected call of GetEvent +// GetEvent indicates an expected call of GetEvent. func (mr *MockClientMockRecorder) GetEvent(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEvent", reflect.TypeOf((*MockClient)(nil).GetEvent), arg0, arg1) } -// GetMailSettings mocks base method +// GetMailSettings mocks base method. func (m *MockClient) GetMailSettings(arg0 context.Context) (pmapi.MailSettings, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetMailSettings", arg0) @@ -339,13 +325,13 @@ func (m *MockClient) GetMailSettings(arg0 context.Context) (pmapi.MailSettings, return ret0, ret1 } -// GetMailSettings indicates an expected call of GetMailSettings +// GetMailSettings indicates an expected call of GetMailSettings. func (mr *MockClientMockRecorder) GetMailSettings(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMailSettings", reflect.TypeOf((*MockClient)(nil).GetMailSettings), arg0) } -// GetMessage mocks base method +// GetMessage mocks base method. func (m *MockClient) GetMessage(arg0 context.Context, arg1 string) (*pmapi.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetMessage", arg0, arg1) @@ -354,13 +340,13 @@ func (m *MockClient) GetMessage(arg0 context.Context, arg1 string) (*pmapi.Messa return ret0, ret1 } -// GetMessage indicates an expected call of GetMessage +// GetMessage indicates an expected call of GetMessage. func (mr *MockClientMockRecorder) GetMessage(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessage", reflect.TypeOf((*MockClient)(nil).GetMessage), arg0, arg1) } -// GetPublicKeysForEmail mocks base method +// GetPublicKeysForEmail mocks base method. func (m *MockClient) GetPublicKeysForEmail(arg0 context.Context, arg1 string) ([]pmapi.PublicKey, bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPublicKeysForEmail", arg0, arg1) @@ -370,13 +356,13 @@ func (m *MockClient) GetPublicKeysForEmail(arg0 context.Context, arg1 string) ([ return ret0, ret1, ret2 } -// GetPublicKeysForEmail indicates an expected call of GetPublicKeysForEmail +// GetPublicKeysForEmail indicates an expected call of GetPublicKeysForEmail. func (mr *MockClientMockRecorder) GetPublicKeysForEmail(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPublicKeysForEmail", reflect.TypeOf((*MockClient)(nil).GetPublicKeysForEmail), arg0, arg1) } -// Import mocks base method +// Import mocks base method. func (m *MockClient) Import(arg0 context.Context, arg1 pmapi.ImportMsgReqs) ([]*pmapi.ImportMsgRes, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Import", arg0, arg1) @@ -385,13 +371,13 @@ func (m *MockClient) Import(arg0 context.Context, arg1 pmapi.ImportMsgReqs) ([]* return ret0, ret1 } -// Import indicates an expected call of Import +// Import indicates an expected call of Import. func (mr *MockClientMockRecorder) Import(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Import", reflect.TypeOf((*MockClient)(nil).Import), arg0, arg1) } -// IsUnlocked mocks base method +// IsUnlocked mocks base method. func (m *MockClient) IsUnlocked() bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsUnlocked") @@ -399,13 +385,13 @@ func (m *MockClient) IsUnlocked() bool { return ret0 } -// IsUnlocked indicates an expected call of IsUnlocked +// IsUnlocked indicates an expected call of IsUnlocked. func (mr *MockClientMockRecorder) IsUnlocked() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsUnlocked", reflect.TypeOf((*MockClient)(nil).IsUnlocked)) } -// KeyRingForAddressID mocks base method +// KeyRingForAddressID mocks base method. func (m *MockClient) KeyRingForAddressID(arg0 string) (*crypto.KeyRing, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "KeyRingForAddressID", arg0) @@ -414,13 +400,13 @@ func (m *MockClient) KeyRingForAddressID(arg0 string) (*crypto.KeyRing, error) { return ret0, ret1 } -// KeyRingForAddressID indicates an expected call of KeyRingForAddressID +// KeyRingForAddressID indicates an expected call of KeyRingForAddressID. func (mr *MockClientMockRecorder) KeyRingForAddressID(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KeyRingForAddressID", reflect.TypeOf((*MockClient)(nil).KeyRingForAddressID), arg0) } -// LabelMessages mocks base method +// LabelMessages mocks base method. func (m *MockClient) LabelMessages(arg0 context.Context, arg1 []string, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LabelMessages", arg0, arg1, arg2) @@ -428,13 +414,13 @@ func (m *MockClient) LabelMessages(arg0 context.Context, arg1 []string, arg2 str return ret0 } -// LabelMessages indicates an expected call of LabelMessages +// LabelMessages indicates an expected call of LabelMessages. func (mr *MockClientMockRecorder) LabelMessages(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LabelMessages", reflect.TypeOf((*MockClient)(nil).LabelMessages), arg0, arg1, arg2) } -// ListLabels mocks base method +// ListLabels mocks base method. func (m *MockClient) ListLabels(arg0 context.Context) ([]*pmapi.Label, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListLabels", arg0) @@ -443,13 +429,13 @@ func (m *MockClient) ListLabels(arg0 context.Context) ([]*pmapi.Label, error) { return ret0, ret1 } -// ListLabels indicates an expected call of ListLabels +// ListLabels indicates an expected call of ListLabels. func (mr *MockClientMockRecorder) ListLabels(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLabels", reflect.TypeOf((*MockClient)(nil).ListLabels), arg0) } -// ListMessages mocks base method +// ListMessages mocks base method. func (m *MockClient) ListMessages(arg0 context.Context, arg1 *pmapi.MessagesFilter) ([]*pmapi.Message, int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListMessages", arg0, arg1) @@ -459,13 +445,13 @@ func (m *MockClient) ListMessages(arg0 context.Context, arg1 *pmapi.MessagesFilt return ret0, ret1, ret2 } -// ListMessages indicates an expected call of ListMessages +// ListMessages indicates an expected call of ListMessages. func (mr *MockClientMockRecorder) ListMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListMessages", reflect.TypeOf((*MockClient)(nil).ListMessages), arg0, arg1) } -// MarkMessagesRead mocks base method +// MarkMessagesRead mocks base method. func (m *MockClient) MarkMessagesRead(arg0 context.Context, arg1 []string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarkMessagesRead", arg0, arg1) @@ -473,13 +459,13 @@ func (m *MockClient) MarkMessagesRead(arg0 context.Context, arg1 []string) error return ret0 } -// MarkMessagesRead indicates an expected call of MarkMessagesRead +// MarkMessagesRead indicates an expected call of MarkMessagesRead. func (mr *MockClientMockRecorder) MarkMessagesRead(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkMessagesRead", reflect.TypeOf((*MockClient)(nil).MarkMessagesRead), arg0, arg1) } -// MarkMessagesUnread mocks base method +// MarkMessagesUnread mocks base method. func (m *MockClient) MarkMessagesUnread(arg0 context.Context, arg1 []string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarkMessagesUnread", arg0, arg1) @@ -487,13 +473,13 @@ func (m *MockClient) MarkMessagesUnread(arg0 context.Context, arg1 []string) err return ret0 } -// MarkMessagesUnread indicates an expected call of MarkMessagesUnread +// MarkMessagesUnread indicates an expected call of MarkMessagesUnread. func (mr *MockClientMockRecorder) MarkMessagesUnread(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkMessagesUnread", reflect.TypeOf((*MockClient)(nil).MarkMessagesUnread), arg0, arg1) } -// ReloadKeys mocks base method +// ReloadKeys mocks base method. func (m *MockClient) ReloadKeys(arg0 context.Context, arg1 []byte) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReloadKeys", arg0, arg1) @@ -501,13 +487,13 @@ func (m *MockClient) ReloadKeys(arg0 context.Context, arg1 []byte) error { return ret0 } -// ReloadKeys indicates an expected call of ReloadKeys +// ReloadKeys indicates an expected call of ReloadKeys. func (mr *MockClientMockRecorder) ReloadKeys(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReloadKeys", reflect.TypeOf((*MockClient)(nil).ReloadKeys), arg0, arg1) } -// ReorderAddresses mocks base method +// ReorderAddresses mocks base method. func (m *MockClient) ReorderAddresses(arg0 context.Context, arg1 []string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReorderAddresses", arg0, arg1) @@ -515,13 +501,13 @@ func (m *MockClient) ReorderAddresses(arg0 context.Context, arg1 []string) error return ret0 } -// ReorderAddresses indicates an expected call of ReorderAddresses +// ReorderAddresses indicates an expected call of ReorderAddresses. func (mr *MockClientMockRecorder) ReorderAddresses(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReorderAddresses", reflect.TypeOf((*MockClient)(nil).ReorderAddresses), arg0, arg1) } -// SendMessage mocks base method +// SendMessage mocks base method. func (m *MockClient) SendMessage(arg0 context.Context, arg1 string, arg2 *pmapi.SendMessageReq) (*pmapi.Message, *pmapi.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendMessage", arg0, arg1, arg2) @@ -531,13 +517,13 @@ func (m *MockClient) SendMessage(arg0 context.Context, arg1 string, arg2 *pmapi. return ret0, ret1, ret2 } -// SendMessage indicates an expected call of SendMessage +// SendMessage indicates an expected call of SendMessage. func (mr *MockClientMockRecorder) SendMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockClient)(nil).SendMessage), arg0, arg1, arg2) } -// UnlabelMessages mocks base method +// UnlabelMessages mocks base method. func (m *MockClient) UnlabelMessages(arg0 context.Context, arg1 []string, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UnlabelMessages", arg0, arg1, arg2) @@ -545,13 +531,13 @@ func (m *MockClient) UnlabelMessages(arg0 context.Context, arg1 []string, arg2 s return ret0 } -// UnlabelMessages indicates an expected call of UnlabelMessages +// UnlabelMessages indicates an expected call of UnlabelMessages. func (mr *MockClientMockRecorder) UnlabelMessages(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnlabelMessages", reflect.TypeOf((*MockClient)(nil).UnlabelMessages), arg0, arg1, arg2) } -// Unlock mocks base method +// Unlock mocks base method. func (m *MockClient) Unlock(arg0 context.Context, arg1 []byte) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Unlock", arg0, arg1) @@ -559,13 +545,13 @@ func (m *MockClient) Unlock(arg0 context.Context, arg1 []byte) error { return ret0 } -// Unlock indicates an expected call of Unlock +// Unlock indicates an expected call of Unlock. func (mr *MockClientMockRecorder) Unlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockClient)(nil).Unlock), arg0, arg1) } -// UpdateLabel mocks base method +// UpdateLabel mocks base method. func (m *MockClient) UpdateLabel(arg0 context.Context, arg1 *pmapi.Label) (*pmapi.Label, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateLabel", arg0, arg1) @@ -574,13 +560,13 @@ func (m *MockClient) UpdateLabel(arg0 context.Context, arg1 *pmapi.Label) (*pmap return ret0, ret1 } -// UpdateLabel indicates an expected call of UpdateLabel +// UpdateLabel indicates an expected call of UpdateLabel. func (mr *MockClientMockRecorder) UpdateLabel(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLabel", reflect.TypeOf((*MockClient)(nil).UpdateLabel), arg0, arg1) } -// UpdateUser mocks base method +// UpdateUser mocks base method. func (m *MockClient) UpdateUser(arg0 context.Context) (*pmapi.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateUser", arg0) @@ -589,72 +575,72 @@ func (m *MockClient) UpdateUser(arg0 context.Context) (*pmapi.User, error) { return ret0, ret1 } -// UpdateUser indicates an expected call of UpdateUser +// UpdateUser indicates an expected call of UpdateUser. func (mr *MockClientMockRecorder) UpdateUser(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockClient)(nil).UpdateUser), arg0) } -// MockManager is a mock of Manager interface +// MockManager is a mock of Manager interface. type MockManager struct { ctrl *gomock.Controller recorder *MockManagerMockRecorder } -// MockManagerMockRecorder is the mock recorder for MockManager +// MockManagerMockRecorder is the mock recorder for MockManager. type MockManagerMockRecorder struct { mock *MockManager } -// NewMockManager creates a new mock instance +// NewMockManager creates a new mock instance. func NewMockManager(ctrl *gomock.Controller) *MockManager { mock := &MockManager{ctrl: ctrl} mock.recorder = &MockManagerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockManager) EXPECT() *MockManagerMockRecorder { return m.recorder } -// AddConnectionObserver mocks base method +// AddConnectionObserver mocks base method. func (m *MockManager) AddConnectionObserver(arg0 pmapi.ConnectionObserver) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddConnectionObserver", arg0) } -// AddConnectionObserver indicates an expected call of AddConnectionObserver +// AddConnectionObserver indicates an expected call of AddConnectionObserver. func (mr *MockManagerMockRecorder) AddConnectionObserver(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddConnectionObserver", reflect.TypeOf((*MockManager)(nil).AddConnectionObserver), arg0) } -// AllowProxy mocks base method +// AllowProxy mocks base method. func (m *MockManager) AllowProxy() { m.ctrl.T.Helper() m.ctrl.Call(m, "AllowProxy") } -// AllowProxy indicates an expected call of AllowProxy +// AllowProxy indicates an expected call of AllowProxy. func (mr *MockManagerMockRecorder) AllowProxy() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllowProxy", reflect.TypeOf((*MockManager)(nil).AllowProxy)) } -// DisallowProxy mocks base method +// DisallowProxy mocks base method. func (m *MockManager) DisallowProxy() { m.ctrl.T.Helper() m.ctrl.Call(m, "DisallowProxy") } -// DisallowProxy indicates an expected call of DisallowProxy +// DisallowProxy indicates an expected call of DisallowProxy. func (mr *MockManagerMockRecorder) DisallowProxy() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisallowProxy", reflect.TypeOf((*MockManager)(nil).DisallowProxy)) } -// DownloadAndVerify mocks base method +// DownloadAndVerify mocks base method. func (m *MockManager) DownloadAndVerify(arg0 *crypto.KeyRing, arg1, arg2 string) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadAndVerify", arg0, arg1, arg2) @@ -663,13 +649,13 @@ func (m *MockManager) DownloadAndVerify(arg0 *crypto.KeyRing, arg1, arg2 string) return ret0, ret1 } -// DownloadAndVerify indicates an expected call of DownloadAndVerify +// DownloadAndVerify indicates an expected call of DownloadAndVerify. func (mr *MockManagerMockRecorder) DownloadAndVerify(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadAndVerify", reflect.TypeOf((*MockManager)(nil).DownloadAndVerify), arg0, arg1, arg2) } -// NewClient mocks base method +// NewClient mocks base method. func (m *MockManager) NewClient(arg0, arg1, arg2 string, arg3 time.Time) pmapi.Client { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewClient", arg0, arg1, arg2, arg3) @@ -677,13 +663,13 @@ func (m *MockManager) NewClient(arg0, arg1, arg2 string, arg3 time.Time) pmapi.C return ret0 } -// NewClient indicates an expected call of NewClient +// NewClient indicates an expected call of NewClient. func (mr *MockManagerMockRecorder) NewClient(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewClient", reflect.TypeOf((*MockManager)(nil).NewClient), arg0, arg1, arg2, arg3) } -// NewClientWithLogin mocks base method +// NewClientWithLogin mocks base method. func (m *MockManager) NewClientWithLogin(arg0 context.Context, arg1 string, arg2 []byte) (pmapi.Client, *pmapi.Auth, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewClientWithLogin", arg0, arg1, arg2) @@ -693,13 +679,13 @@ func (m *MockManager) NewClientWithLogin(arg0 context.Context, arg1 string, arg2 return ret0, ret1, ret2 } -// NewClientWithLogin indicates an expected call of NewClientWithLogin +// NewClientWithLogin indicates an expected call of NewClientWithLogin. func (mr *MockManagerMockRecorder) NewClientWithLogin(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewClientWithLogin", reflect.TypeOf((*MockManager)(nil).NewClientWithLogin), arg0, arg1, arg2) } -// NewClientWithRefresh mocks base method +// NewClientWithRefresh mocks base method. func (m *MockManager) NewClientWithRefresh(arg0 context.Context, arg1, arg2 string) (pmapi.Client, *pmapi.AuthRefresh, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewClientWithRefresh", arg0, arg1, arg2) @@ -709,13 +695,13 @@ func (m *MockManager) NewClientWithRefresh(arg0 context.Context, arg1, arg2 stri return ret0, ret1, ret2 } -// NewClientWithRefresh indicates an expected call of NewClientWithRefresh +// NewClientWithRefresh indicates an expected call of NewClientWithRefresh. func (mr *MockManagerMockRecorder) NewClientWithRefresh(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewClientWithRefresh", reflect.TypeOf((*MockManager)(nil).NewClientWithRefresh), arg0, arg1, arg2) } -// ReportBug mocks base method +// ReportBug mocks base method. func (m *MockManager) ReportBug(arg0 context.Context, arg1 pmapi.ReportBugReq) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReportBug", arg0, arg1) @@ -723,13 +709,13 @@ func (m *MockManager) ReportBug(arg0 context.Context, arg1 pmapi.ReportBugReq) e return ret0 } -// ReportBug indicates an expected call of ReportBug +// ReportBug indicates an expected call of ReportBug. func (mr *MockManagerMockRecorder) ReportBug(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportBug", reflect.TypeOf((*MockManager)(nil).ReportBug), arg0, arg1) } -// SendSimpleMetric mocks base method +// SendSimpleMetric mocks base method. func (m *MockManager) SendSimpleMetric(arg0 context.Context, arg1, arg2, arg3 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendSimpleMetric", arg0, arg1, arg2, arg3) @@ -737,55 +723,55 @@ func (m *MockManager) SendSimpleMetric(arg0 context.Context, arg1, arg2, arg3 st return ret0 } -// SendSimpleMetric indicates an expected call of SendSimpleMetric +// SendSimpleMetric indicates an expected call of SendSimpleMetric. func (mr *MockManagerMockRecorder) SendSimpleMetric(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendSimpleMetric", reflect.TypeOf((*MockManager)(nil).SendSimpleMetric), arg0, arg1, arg2, arg3) } -// SetCookieJar mocks base method +// SetCookieJar mocks base method. func (m *MockManager) SetCookieJar(arg0 http.CookieJar) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetCookieJar", arg0) } -// SetCookieJar indicates an expected call of SetCookieJar +// SetCookieJar indicates an expected call of SetCookieJar. func (mr *MockManagerMockRecorder) SetCookieJar(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCookieJar", reflect.TypeOf((*MockManager)(nil).SetCookieJar), arg0) } -// SetLogging mocks base method +// SetLogging mocks base method. func (m *MockManager) SetLogging(arg0 *logrus.Entry, arg1 bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetLogging", arg0, arg1) } -// SetLogging indicates an expected call of SetLogging +// SetLogging indicates an expected call of SetLogging. func (mr *MockManagerMockRecorder) SetLogging(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogging", reflect.TypeOf((*MockManager)(nil).SetLogging), arg0, arg1) } -// SetRetryCount mocks base method +// SetRetryCount mocks base method. func (m *MockManager) SetRetryCount(arg0 int) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetRetryCount", arg0) } -// SetRetryCount indicates an expected call of SetRetryCount +// SetRetryCount indicates an expected call of SetRetryCount. func (mr *MockManagerMockRecorder) SetRetryCount(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRetryCount", reflect.TypeOf((*MockManager)(nil).SetRetryCount), arg0) } -// SetTransport mocks base method +// SetTransport mocks base method. func (m *MockManager) SetTransport(arg0 http.RoundTripper) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetTransport", arg0) } -// SetTransport indicates an expected call of SetTransport +// SetTransport indicates an expected call of SetTransport. func (mr *MockManagerMockRecorder) SetTransport(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTransport", reflect.TypeOf((*MockManager)(nil).SetTransport), arg0) diff --git a/test/context/users.go b/test/context/users.go index ee8d2db5..1fb440b7 100644 --- a/test/context/users.go +++ b/test/context/users.go @@ -64,7 +64,16 @@ func (ctx *TestContext) LoginUser(username string, password, mailboxPassword []b // FinishLogin prevents authentication if not necessary. func (ctx *TestContext) FinishLogin(client pmapi.Client, mailboxPassword []byte) error { - user, err := ctx.users.FinishLogin(client, client.GetCurrentAuth(), mailboxPassword) + type currentAuthGetter interface { + GetCurrentAuth() *pmapi.Auth + } + + c, ok := client.(currentAuthGetter) + if c == nil || !ok { + return errors.New("cannot get current auth tokens from client") + } + + user, err := ctx.users.FinishLogin(client, c.GetCurrentAuth(), mailboxPassword) if err != nil { return errors.Wrap(err, "failed to finish login") } diff --git a/test/liveapi/persistent_clients.go b/test/liveapi/persistent_clients.go index 404d76b2..46538995 100644 --- a/test/liveapi/persistent_clients.go +++ b/test/liveapi/persistent_clients.go @@ -30,6 +30,11 @@ import ( "github.com/sirupsen/logrus" ) +type clientAuthGetter interface { + pmapi.Client + GetCurrentAuth() *pmapi.Auth +} + // persistentClients keeps authenticated clients for tests. // // We need to reduce the number of authentication done by live tests. @@ -37,15 +42,15 @@ import ( // This is not necessary for controller purposes. We can reuse the same clients // for all tests. // -//nolint[gochecknoglobals] +//nolint:gochecknoglobals // This is necessary for testing var persistentClients = struct { manager pmapi.Manager - byName map[string]pmapi.Client + byName map[string]clientAuthGetter saltByName map[string]string }{} type persistentClient struct { - pmapi.Client + clientAuthGetter username string } @@ -70,7 +75,7 @@ func SetupPersistentClients() { persistentClients.manager = pmapi.New(pmapi.NewConfig(getAppVersionName(app), constants.Version)) persistentClients.manager.SetLogging(logrus.WithField("pkg", "liveapi"), logrus.GetLevel() == logrus.TraceLevel) - persistentClients.byName = map[string]pmapi.Client{} + persistentClients.byName = map[string]clientAuthGetter{} persistentClients.saltByName = map[string]string{} } @@ -96,13 +101,18 @@ func addPersistentClient(username string, password, mailboxPassword []byte) (pma return cl, nil } - srp.RandReader = rand.New(rand.NewSource(42)) //nolint[gosec] It is OK to use weaker random number generator here + srp.RandReader = rand.New(rand.NewSource(42)) //nolint:gosec // It is OK to use weaker random number generator here - client, _, err := persistentClients.manager.NewClientWithLogin(context.Background(), username, password) + normalClient, _, err := persistentClients.manager.NewClientWithLogin(context.Background(), username, password) if err != nil { return nil, errors.Wrap(err, "failed to create new persistent client") } + client, ok := normalClient.(clientAuthGetter) + if !ok { + return nil, errors.New("cannot make clientAuthGetter") + } + salt, err := client.AuthSalt(context.Background()) if err != nil { return nil, errors.Wrap(err, "persistent client: failed to get salt") From 1d4ee0c33e243f096d97260f46576f77369a873a Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 14 Jun 2021 09:07:50 +0200 Subject: [PATCH 8/8] Other: Bridge 1.8.6 --- Changelog.md | 12 ++++++++++++ Makefile | 2 +- test/Makefile | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 49143f7e..c6fa083b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,18 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## [Bridge 1.8.6] James + +### Removed +* GODT-1187: Remove IMAP/SMTP blocking when no internet. + +### Changed +* GODT-1166: Reduce the number of auth for live test. + +### Fixed +* GODT-1193: Do not use message.Read permit non-UTF-8 charsets. + + ## [Bridge 1.8.5] James ### Fixed diff --git a/Makefile b/Makefile index a69a7b81..7fe0f7fd 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ TARGET_OS?=${GOOS} .PHONY: build build-ie build-nogui build-ie-nogui build-launcher build-launcher-ie versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=1.8.5+git +BRIDGE_APP_VERSION?=1.8.6+git IE_APP_VERSION?=1.3.3+git APP_VERSION:=${BRIDGE_APP_VERSION} SRC_ICO:=logo.ico diff --git a/test/Makefile b/test/Makefile index ff21c606..61f43340 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ .PHONY: check-go check-godog install-godog test test-bridge test-ie test-live test-live-bridge test-live-ie test-stage test-debug test-live-debug bench export GO111MODULE=on -export BRIDGE_VERSION:=1.8.2+integrationtests +export BRIDGE_VERSION:=1.8.6+integrationtests export VERBOSITY?=fatal export TEST_DATA=testdata export TEST_APP?=bridge