forked from Silverfish/proton-bridge
We build too many walls and not enough bridges
This commit is contained in:
192
test/accounts/account.go
Normal file
192
test/accounts/account.go
Normal file
@ -0,0 +1,192 @@
|
||||
// Copyright (c) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
)
|
||||
|
||||
const (
|
||||
testUserKey = "user_key.json"
|
||||
testAddressKey = "address_key.json"
|
||||
testKeyPassphrase = "testpassphrase"
|
||||
)
|
||||
|
||||
type TestAccount struct {
|
||||
user *pmapi.User
|
||||
addressToBeUsed *pmapi.Address
|
||||
addressesByBDDAddressID map[string]*pmapi.Address
|
||||
password string
|
||||
mailboxPassword string
|
||||
twoFAEnabled bool
|
||||
}
|
||||
|
||||
func newTestAccount(
|
||||
user *pmapi.User,
|
||||
addressesByBDDAddressID map[string]*pmapi.Address,
|
||||
addressIDToBeUsed string,
|
||||
password,
|
||||
mailboxPassword string,
|
||||
twoFAEnabled bool,
|
||||
) *TestAccount {
|
||||
account := &TestAccount{
|
||||
user: user,
|
||||
addressesByBDDAddressID: addressesByBDDAddressID,
|
||||
password: password,
|
||||
mailboxPassword: mailboxPassword,
|
||||
twoFAEnabled: twoFAEnabled,
|
||||
}
|
||||
|
||||
if addressIDToBeUsed == "" {
|
||||
account.addressToBeUsed = account.Addresses().Main()
|
||||
} else {
|
||||
for addressID, address := range addressesByBDDAddressID {
|
||||
if addressID == addressIDToBeUsed {
|
||||
account.addressToBeUsed = address
|
||||
}
|
||||
}
|
||||
}
|
||||
if account.addressToBeUsed == nil {
|
||||
// Return nothing which will be interpreted as not implemented the same way the whole account.
|
||||
return nil
|
||||
}
|
||||
|
||||
account.initKeys()
|
||||
return account
|
||||
}
|
||||
|
||||
func (a *TestAccount) initKeys() {
|
||||
if a.user.Keys.Keys != nil {
|
||||
return
|
||||
}
|
||||
userKeys := loadPMKeys(readTestFile(testUserKey))
|
||||
_ = userKeys.KeyRing.Unlock([]byte(testKeyPassphrase))
|
||||
|
||||
addressKeys := loadPMKeys(readTestFile(testAddressKey))
|
||||
_ = addressKeys.KeyRing.Unlock([]byte(testKeyPassphrase))
|
||||
|
||||
a.user.Keys = *userKeys
|
||||
for _, addressEmail := range a.Addresses().ActiveEmails() {
|
||||
a.Addresses().ByEmail(addressEmail).Keys = *addressKeys
|
||||
}
|
||||
}
|
||||
|
||||
func readTestFile(fileName string) []byte {
|
||||
testDataFolder := os.Getenv("TEST_DATA")
|
||||
path := filepath.Join(testDataFolder, fileName)
|
||||
data, err := ioutil.ReadFile(path) //nolint[gosec]
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func loadPMKeys(jsonKeys []byte) (keys *pmapi.PMKeys) {
|
||||
_ = json.Unmarshal(jsonKeys, &keys)
|
||||
return
|
||||
}
|
||||
|
||||
func (a *TestAccount) User() *pmapi.User {
|
||||
return a.user
|
||||
}
|
||||
|
||||
func (a *TestAccount) UserID() string {
|
||||
return a.user.ID
|
||||
}
|
||||
|
||||
func (a *TestAccount) Username() string {
|
||||
return a.user.Name
|
||||
}
|
||||
|
||||
func (a *TestAccount) Addresses() *pmapi.AddressList {
|
||||
addressArray := []*pmapi.Address{}
|
||||
for _, address := range a.addressesByBDDAddressID {
|
||||
addressArray = append(addressArray, address)
|
||||
}
|
||||
// The order of addresses is important in PMAPI because the primary
|
||||
// address is always the first in array. We are using map to define
|
||||
// testing addresses which can cause random re-schuffle between tests
|
||||
sort.SliceStable(
|
||||
addressArray,
|
||||
func(i, j int) bool {
|
||||
return addressArray[i].Order < addressArray[j].Order
|
||||
},
|
||||
)
|
||||
addresses := pmapi.AddressList(addressArray)
|
||||
return &addresses
|
||||
}
|
||||
|
||||
func (a *TestAccount) Address() string {
|
||||
return a.addressToBeUsed.Email
|
||||
}
|
||||
|
||||
func (a *TestAccount) AddressID() string {
|
||||
return a.addressToBeUsed.ID
|
||||
}
|
||||
|
||||
// EnsureAddressID accepts address (simply the address) or bddAddressID used
|
||||
// in tests (in format [bddAddressID]) and returns always the real address ID.
|
||||
// If the address is not found, the ID of main address is returned.
|
||||
func (a *TestAccount) EnsureAddressID(addressOrAddressTestID string) string {
|
||||
if strings.HasPrefix(addressOrAddressTestID, "[") {
|
||||
addressTestID := addressOrAddressTestID[1 : len(addressOrAddressTestID)-1]
|
||||
address := a.addressesByBDDAddressID[addressTestID]
|
||||
return address.ID
|
||||
}
|
||||
for _, address := range a.addressesByBDDAddressID {
|
||||
if address.Email == addressOrAddressTestID {
|
||||
return address.ID
|
||||
}
|
||||
}
|
||||
return a.AddressID()
|
||||
}
|
||||
|
||||
// EnsureAddress accepts address (simply the address) or bddAddressID used
|
||||
// in tests (in format [bddAddressID]) and returns always the address.
|
||||
// If the address ID cannot be found, the original value is returned.
|
||||
func (a *TestAccount) EnsureAddress(addressOrAddressTestID string) string {
|
||||
if strings.HasPrefix(addressOrAddressTestID, "[") {
|
||||
addressTestID := addressOrAddressTestID[1 : len(addressOrAddressTestID)-1]
|
||||
address := a.addressesByBDDAddressID[addressTestID]
|
||||
return address.Email
|
||||
}
|
||||
return addressOrAddressTestID
|
||||
}
|
||||
|
||||
func (a *TestAccount) Password() string {
|
||||
return a.password
|
||||
}
|
||||
|
||||
func (a *TestAccount) MailboxPassword() string {
|
||||
return a.mailboxPassword
|
||||
}
|
||||
|
||||
func (a *TestAccount) IsTwoFAEnabled() bool {
|
||||
return a.twoFAEnabled
|
||||
}
|
||||
|
||||
func (a *TestAccount) BridgePassword() string {
|
||||
return BridgePassword
|
||||
}
|
||||
79
test/accounts/accounts.go
Normal file
79
test/accounts/accounts.go
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2020 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// BridgePassword is password to be used for IMAP or SMTP under tests.
|
||||
const BridgePassword = "bridgepassword"
|
||||
|
||||
type TestAccounts struct {
|
||||
Users map[string]*pmapi.User // Key is user ID used in BDD.
|
||||
Addresses map[string]map[string]*pmapi.Address // Key is real user ID, second key is address ID used in BDD.
|
||||
Passwords map[string]string // Key is real user ID.
|
||||
MailboxPasswords map[string]string // Key is real user ID.
|
||||
TwoFAs map[string]bool // Key is real user ID.
|
||||
}
|
||||
|
||||
func Load(path string) (*TestAccounts, error) {
|
||||
data, err := ioutil.ReadFile(path) //nolint[gosec]
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load JSON")
|
||||
}
|
||||
|
||||
var testAccounts TestAccounts
|
||||
err = json.Unmarshal(data, &testAccounts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal JSON")
|
||||
}
|
||||
|
||||
return &testAccounts, nil
|
||||
}
|
||||
|
||||
func (a *TestAccounts) GetTestAccount(username string) *TestAccount {
|
||||
return a.GetTestAccountWithAddress(username, "")
|
||||
}
|
||||
|
||||
func (a *TestAccounts) GetTestAccountWithAddress(username, addressID string) *TestAccount {
|
||||
// Do lookup by full address and convert to name in tests.
|
||||
// Used by getting real data to ensure correct address or address ID.
|
||||
for key, user := range a.Users {
|
||||
if user.Name == username {
|
||||
username = key
|
||||
break
|
||||
}
|
||||
}
|
||||
user, ok := a.Users[username]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return newTestAccount(
|
||||
user,
|
||||
a.Addresses[user.Name],
|
||||
addressID,
|
||||
a.Passwords[user.Name],
|
||||
a.MailboxPasswords[user.Name],
|
||||
a.TwoFAs[user.Name],
|
||||
)
|
||||
}
|
||||
105
test/accounts/fake.json
Normal file
105
test/accounts/fake.json
Normal file
@ -0,0 +1,105 @@
|
||||
{
|
||||
"users": {
|
||||
"user": {
|
||||
"ID": "1",
|
||||
"Name": "user"
|
||||
},
|
||||
"user2fa": {
|
||||
"ID": "2",
|
||||
"Name": "user2fa"
|
||||
},
|
||||
"userAddressWithCapitalLetter": {
|
||||
"ID": "3",
|
||||
"Name": "userAddressWithCapitalLetter"
|
||||
},
|
||||
"userMoreAddresses": {
|
||||
"ID": "4",
|
||||
"Name": "userMoreAddresses"
|
||||
},
|
||||
"userDisabledPrimaryAddress": {
|
||||
"ID": "5",
|
||||
"Name": "userDisabledPrimaryAddress"
|
||||
}
|
||||
},
|
||||
"addresses": {
|
||||
"user": {
|
||||
"userAddress": {
|
||||
"ID": "userAddress",
|
||||
"Email": "user@pm.me",
|
||||
"Order": 1,
|
||||
"Receive": 1
|
||||
}
|
||||
},
|
||||
"user2fa": {
|
||||
"user2faAddress": {
|
||||
"ID": "user2faAddress",
|
||||
"Email": "user@pm.me",
|
||||
"Order": 1,
|
||||
"Receive": 1
|
||||
}
|
||||
},
|
||||
"userAddressWithCapitalLetter": {
|
||||
"userAddressWithCapitalLetterAddress": {
|
||||
"ID": "userAddressWithCapitalLetterAddress",
|
||||
"Email": "uSeR@pm.me",
|
||||
"Order": 1,
|
||||
"Receive": 1
|
||||
}
|
||||
},
|
||||
"userMoreAddresses": {
|
||||
"primary": {
|
||||
"ID": "primary",
|
||||
"Email": "primaryaddress@pm.me",
|
||||
"Order": 1,
|
||||
"Receive": 1
|
||||
},
|
||||
"secondary": {
|
||||
"ID": "secondary",
|
||||
"Email": "secondaryaddress@pm.me",
|
||||
"Order": 2,
|
||||
"Receive": 1
|
||||
},
|
||||
"disabled": {
|
||||
"ID": "disabled",
|
||||
"Email": "disabledaddress@pm.me",
|
||||
"Order": 3,
|
||||
"Receive": 0
|
||||
}
|
||||
},
|
||||
"userDisabledPrimaryAddress": {
|
||||
"primary": {
|
||||
"ID": "primary",
|
||||
"Email": "user@pm.me",
|
||||
"Order": 1,
|
||||
"Receive": 0
|
||||
},
|
||||
"secondary": {
|
||||
"ID": "secondary",
|
||||
"Email": "user@pm.me",
|
||||
"Order": 2,
|
||||
"Receive": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"passwords": {
|
||||
"user": "password",
|
||||
"user2fa": "password",
|
||||
"userAddressWithCapitalLetter": "password",
|
||||
"userMoreAddresses": "password",
|
||||
"userDisabledPrimaryAddress": "password"
|
||||
},
|
||||
"mailboxPasswords": {
|
||||
"user": "password",
|
||||
"user2fa": "password",
|
||||
"userAddressWithCapitalLetter": "password",
|
||||
"userMoreAddresses": "password",
|
||||
"userDisabledPrimaryAddress": "password"
|
||||
},
|
||||
"twoFAs": {
|
||||
"user": false,
|
||||
"user2fa": true,
|
||||
"userAddressWithCapitalLetter": false,
|
||||
"userMoreAddresses": false,
|
||||
"userDisabledPrimaryAddress": false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user