Other: Only listen on localhost and add send test

We should only listen on constants.Host when serving IMAP and SMTP.
This change fixes that. It also adds a test that we can send over SMTP
and receive over IMAP.
This commit is contained in:
James Houlahan
2022-10-28 13:38:16 +02:00
parent cb42358e2f
commit 93d9ae32fc
7 changed files with 124 additions and 11 deletions

View File

@ -0,0 +1,98 @@
// Copyright (c) 2022 Proton AG
//
// This file is part of Proton Mail Bridge.
//
// Proton Mail 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.
//
// Proton Mail 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 Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
package bridge_test
import (
"context"
"fmt"
"net/smtp"
"testing"
"time"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
"github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
)
func TestBridge_Send(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) {
_, _, err := s.CreateUser("recipient", "recipient@pm.me", password)
require.NoError(t, err)
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
senderUserID, err := bridge.LoginFull(ctx, username, password, nil, nil)
require.NoError(t, err)
recipientUserID, err := bridge.LoginFull(ctx, "recipient", password, nil, nil)
require.NoError(t, err)
senderInfo, err := bridge.GetUserInfo(senderUserID)
require.NoError(t, err)
recipientInfo, err := bridge.GetUserInfo(recipientUserID)
require.NoError(t, err)
for i := 0; i < 10; i++ {
// Send an email from sender to recipient.
smtpClient, err := smtp.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetSMTPPort()))
require.NoError(t, err)
defer smtpClient.Close() //nolint:errcheck
require.NoError(t, smtpClient.Auth(smtp.PlainAuth("", senderInfo.Addresses[0], string(senderInfo.BridgePass), constants.Host)))
require.NoError(t, smtpClient.Mail(senderInfo.Addresses[0]))
require.NoError(t, smtpClient.Rcpt("recipient@pm.me"))
wc, err := smtpClient.Data()
require.NoError(t, err)
n, err := fmt.Fprintf(wc, "Subject: Test %v\r\n\r\nHello world!", i)
require.NoError(t, err)
require.Greater(t, n, 0)
require.NoError(t, wc.Close())
// Sender should see the message in the Sent folder.
senderIMAPClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
require.NoError(t, err)
require.NoError(t, senderIMAPClient.Login(senderInfo.Addresses[0], string(senderInfo.BridgePass)))
defer senderIMAPClient.Logout() //nolint:errcheck
require.Eventually(t, func() bool {
status, err := senderIMAPClient.Status(`Sent`, []imap.StatusItem{imap.StatusMessages})
require.NoError(t, err)
return status.Messages == uint32(i+1)
}, 10*time.Second, 100*time.Millisecond)
// Recipient should see the message in the Inbox.
recipientIMAPClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
require.NoError(t, err)
require.NoError(t, recipientIMAPClient.Login(recipientInfo.Addresses[0], string(recipientInfo.BridgePass)))
defer recipientIMAPClient.Logout() //nolint:errcheck
require.Eventually(t, func() bool {
status, err := recipientIMAPClient.Status(`Inbox`, []imap.StatusItem{imap.StatusMessages})
require.NoError(t, err)
return status.Messages == uint32(i+1)
}, 10*time.Second, 100*time.Millisecond)
}
})
})
}