mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-22 18:16:43 +00:00
GODT-35: New pmapi client and manager using resty
This commit is contained in:
@ -26,6 +26,7 @@ import (
|
||||
"github.com/ProtonMail/proton-bridge/internal/sentry"
|
||||
"github.com/ProtonMail/proton-bridge/internal/users"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
)
|
||||
|
||||
// GetBridge returns bridge instance.
|
||||
@ -52,7 +53,6 @@ func (ctx *TestContext) RestartBridge() error {
|
||||
_ = user.GetStore().Close()
|
||||
}
|
||||
|
||||
ctx.bridge.StopWatchers()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
ctx.withBridgeInstance()
|
||||
@ -68,7 +68,7 @@ func newBridgeInstance(
|
||||
settings *fakeSettings,
|
||||
credStore users.CredentialsStorer,
|
||||
eventListener listener.Listener,
|
||||
clientManager users.ClientManager,
|
||||
clientManager pmapi.Manager,
|
||||
) *bridge.Bridge {
|
||||
sentryReporter := sentry.NewReporter("bridge", constants.Version, useragent.New())
|
||||
panicHandler := &panicHandler{t: t}
|
||||
|
||||
@ -23,7 +23,6 @@ import (
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/internal/bridge"
|
||||
"github.com/ProtonMail/proton-bridge/internal/config/useragent"
|
||||
"github.com/ProtonMail/proton-bridge/internal/constants"
|
||||
"github.com/ProtonMail/proton-bridge/internal/importexport"
|
||||
"github.com/ProtonMail/proton-bridge/internal/transfer"
|
||||
"github.com/ProtonMail/proton-bridge/internal/users"
|
||||
@ -53,7 +52,7 @@ type TestContext struct {
|
||||
// pmapiController is used to control real or fake pmapi clients.
|
||||
// The clients are created by the clientManager.
|
||||
pmapiController PMAPIController
|
||||
clientManager *pmapi.ClientManager
|
||||
clientManager pmapi.Manager
|
||||
|
||||
// Core related variables.
|
||||
bridge *bridge.Bridge
|
||||
@ -99,10 +98,7 @@ func New(app string) *TestContext {
|
||||
|
||||
userAgent := useragent.New()
|
||||
|
||||
cm := pmapi.NewClientManager(
|
||||
pmapi.GetAPIConfig(getConfigName(app), constants.Version),
|
||||
userAgent,
|
||||
)
|
||||
pmapiController, clientManager := newPMAPIController()
|
||||
|
||||
ctx := &TestContext{
|
||||
t: &bddT{},
|
||||
@ -111,8 +107,8 @@ func New(app string) *TestContext {
|
||||
settings: newFakeSettings(),
|
||||
listener: listener.New(),
|
||||
userAgent: userAgent,
|
||||
pmapiController: newPMAPIController(cm),
|
||||
clientManager: cm,
|
||||
pmapiController: pmapiController,
|
||||
clientManager: clientManager,
|
||||
testAccounts: newTestAccounts(),
|
||||
credStore: newFakeCredStore(),
|
||||
imapClients: make(map[string]*mocks.IMAPClient),
|
||||
@ -164,7 +160,7 @@ func (ctx *TestContext) GetPMAPIController() PMAPIController {
|
||||
}
|
||||
|
||||
// GetClientManager returns client manager being used for testing.
|
||||
func (ctx *TestContext) GetClientManager() *pmapi.ClientManager {
|
||||
func (ctx *TestContext) GetClientManager() pmapi.Manager {
|
||||
return ctx.clientManager
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ func (c *fakeCredStore) List() (userIDs []string, err error) {
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (c *fakeCredStore) Add(userID, userName, apiToken, mailboxPassword string, emails []string) (*credentials.Credentials, error) {
|
||||
func (c *fakeCredStore) Add(userID, userName, uid, ref, mailboxPassword string, emails []string) (*credentials.Credentials, error) {
|
||||
bridgePassword := bridgePassword
|
||||
if c, ok := c.credentials[userID]; ok {
|
||||
bridgePassword = c.BridgePassword
|
||||
@ -60,7 +60,7 @@ func (c *fakeCredStore) Add(userID, userName, apiToken, mailboxPassword string,
|
||||
UserID: userID,
|
||||
Name: userName,
|
||||
Emails: strings.Join(emails, ";"),
|
||||
APIToken: apiToken,
|
||||
APIToken: uid + ":" + ref,
|
||||
MailboxPassword: mailboxPassword,
|
||||
BridgePassword: bridgePassword,
|
||||
IsCombinedAddressMode: true, // otherwise by default starts in split mode
|
||||
@ -73,36 +73,38 @@ func (c *fakeCredStore) Get(userID string) (*credentials.Credentials, error) {
|
||||
return c.credentials[userID], nil
|
||||
}
|
||||
|
||||
func (c *fakeCredStore) SwitchAddressMode(userID string) error {
|
||||
return nil
|
||||
func (c *fakeCredStore) SwitchAddressMode(userID string) (*credentials.Credentials, error) {
|
||||
// FIXME(conman): Why is this empty?
|
||||
return c.credentials[userID], nil
|
||||
}
|
||||
|
||||
func (c *fakeCredStore) UpdateEmails(userID string, emails []string) error {
|
||||
return nil
|
||||
func (c *fakeCredStore) UpdateEmails(userID string, emails []string) (*credentials.Credentials, error) {
|
||||
// FIXME(conman): Why is this empty?
|
||||
return c.credentials[userID], nil
|
||||
}
|
||||
|
||||
func (c *fakeCredStore) UpdatePassword(userID, password string) error {
|
||||
func (c *fakeCredStore) UpdatePassword(userID, password string) (*credentials.Credentials, error) {
|
||||
creds, err := c.Get(userID)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
creds.MailboxPassword = password
|
||||
return nil
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
func (c *fakeCredStore) UpdateToken(userID, apiToken string) error {
|
||||
func (c *fakeCredStore) UpdateToken(userID, uid, ref string) (*credentials.Credentials, error) {
|
||||
creds, err := c.Get(userID)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
creds.APIToken = apiToken
|
||||
return nil
|
||||
creds.APIToken = uid + ":" + ref
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
func (c *fakeCredStore) Logout(userID string) error {
|
||||
func (c *fakeCredStore) Logout(userID string) (*credentials.Credentials, error) {
|
||||
c.credentials[userID].APIToken = ""
|
||||
c.credentials[userID].MailboxPassword = ""
|
||||
return nil
|
||||
return c.credentials[userID], nil
|
||||
}
|
||||
|
||||
func (c *fakeCredStore) Delete(userID string) error {
|
||||
|
||||
@ -21,6 +21,7 @@ import (
|
||||
"github.com/ProtonMail/proton-bridge/internal/importexport"
|
||||
"github.com/ProtonMail/proton-bridge/internal/users"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
)
|
||||
|
||||
// GetImportExport returns import-export instance.
|
||||
@ -42,7 +43,7 @@ func newImportExportInstance(
|
||||
cache importexport.Cacher,
|
||||
credStore users.CredentialsStorer,
|
||||
eventListener listener.Listener,
|
||||
clientManager users.ClientManager,
|
||||
clientManager pmapi.Manager,
|
||||
) *importexport.ImportExport {
|
||||
panicHandler := &panicHandler{t: t}
|
||||
return importexport.New(locations, cache, panicHandler, eventListener, clientManager, credStore)
|
||||
|
||||
@ -39,37 +39,15 @@ type PMAPIController interface {
|
||||
GetCalls(method, path string) [][]byte
|
||||
}
|
||||
|
||||
func newPMAPIController(cm *pmapi.ClientManager) PMAPIController {
|
||||
func newPMAPIController() (PMAPIController, pmapi.Manager) {
|
||||
switch os.Getenv(EnvName) {
|
||||
case EnvFake:
|
||||
return newFakePMAPIController(cm)
|
||||
return fakeapi.NewController()
|
||||
|
||||
case EnvLive:
|
||||
return newLivePMAPIController(cm)
|
||||
return liveapi.NewController()
|
||||
|
||||
default:
|
||||
panic("unknown env")
|
||||
}
|
||||
}
|
||||
|
||||
func newFakePMAPIController(cm *pmapi.ClientManager) PMAPIController {
|
||||
return newFakePMAPIControllerWrap(fakeapi.NewController(cm))
|
||||
}
|
||||
|
||||
type fakePMAPIControllerWrap struct {
|
||||
*fakeapi.Controller
|
||||
}
|
||||
|
||||
func newFakePMAPIControllerWrap(controller *fakeapi.Controller) PMAPIController {
|
||||
return &fakePMAPIControllerWrap{Controller: controller}
|
||||
}
|
||||
|
||||
func newLivePMAPIController(cm *pmapi.ClientManager) PMAPIController {
|
||||
return newLiveAPIControllerWrap(liveapi.NewController(cm))
|
||||
}
|
||||
|
||||
type liveAPIControllerWrap struct {
|
||||
*liveapi.Controller
|
||||
}
|
||||
|
||||
func newLiveAPIControllerWrap(controller *liveapi.Controller) PMAPIController {
|
||||
return &liveAPIControllerWrap{Controller: controller}
|
||||
}
|
||||
|
||||
65
test/context/pmapi_manager.go
Normal file
65
test/context/pmapi_manager.go
Normal file
@ -0,0 +1,65 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
func newLivePMAPIManager() pmapi.Manager {
|
||||
return pmapi.New(pmapi.DefaultConfig)
|
||||
}
|
||||
|
||||
func newFakePMAPIManager() pmapi.Manager {
|
||||
return &fakePMAPIManager{}
|
||||
}
|
||||
|
||||
type fakePMAPIManager struct{}
|
||||
|
||||
func (*fakePMAPIManager) NewClient(string, string, string, time.Time) pmapi.Client {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) NewClientWithRefresh(context.Context, string, string) (pmapi.Client, *pmapi.Auth, error) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) NewClientWithLogin(context.Context, string, string) (pmapi.Client, *pmapi.Auth, error) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) DownloadAndVerify(kr *crypto.KeyRing, url, sig string) ([]byte, error) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) ReportBug(context.Context, pmapi.ReportBugReq) error {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) SendSimpleMetric(context.Context, string, string, string) error {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) SetLogger(resty.Logger) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) SetTransport(http.RoundTripper) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) SetCookieJar(http.CookieJar) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) SetRetryCount(int) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func (*fakePMAPIManager) AddConnectionObserver(pmapi.ConnectionObserver) {
|
||||
panic("TODO")
|
||||
}
|
||||
@ -18,6 +18,7 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"path/filepath"
|
||||
@ -25,6 +26,7 @@ import (
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/internal/store"
|
||||
"github.com/ProtonMail/proton-bridge/internal/users"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/srp"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -36,7 +38,7 @@ func (ctx *TestContext) GetUsers() *users.Users {
|
||||
}
|
||||
|
||||
// LoginUser logs in the user with the given username, password, and mailbox password.
|
||||
func (ctx *TestContext) LoginUser(username, password, mailboxPassword string) (err error) {
|
||||
func (ctx *TestContext) LoginUser(username, password, mailboxPassword string) error {
|
||||
srp.RandReader = rand.New(rand.NewSource(42)) //nolint[gosec] It is OK to use weaker random number generator here
|
||||
|
||||
client, auth, err := ctx.users.Login(username, password)
|
||||
@ -44,8 +46,8 @@ func (ctx *TestContext) LoginUser(username, password, mailboxPassword string) (e
|
||||
return errors.Wrap(err, "failed to login")
|
||||
}
|
||||
|
||||
if auth.HasTwoFactor() {
|
||||
if err := client.Auth2FA("2fa code", auth); err != nil {
|
||||
if auth.TwoFA.Enabled == pmapi.TOTPEnabled {
|
||||
if err := client.Auth2FA(context.TODO(), pmapi.Auth2FAReq{TwoFactorCode: "2fa code"}); err != nil {
|
||||
return errors.Wrap(err, "failed to login with 2FA")
|
||||
}
|
||||
}
|
||||
@ -57,7 +59,7 @@ func (ctx *TestContext) LoginUser(username, password, mailboxPassword string) (e
|
||||
|
||||
ctx.addCleanupChecked(user.Logout, "Logging out user")
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUser retrieves the bridge user matching the given query string.
|
||||
|
||||
Reference in New Issue
Block a user