Skip to content

Commit

Permalink
feat/wallet-config-sensitive-string
Browse files Browse the repository at this point in the history
  • Loading branch information
igor-sirotin committed Dec 11, 2024
1 parent 21c85e2 commit cdf9304
Show file tree
Hide file tree
Showing 16 changed files with 133 additions and 122 deletions.
26 changes: 16 additions & 10 deletions api/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import (
"github.com/status-im/status-go/t/helpers"
"github.com/status-im/status-go/t/utils"
"github.com/status-im/status-go/walletdatabase"
"github.com/status-im/status-go/internal/security"
"github.com/brianvoe/gofakeit/v6"
)

var (
Expand Down Expand Up @@ -1515,20 +1517,24 @@ func TestSetFleet(t *testing.T) {
require.NoError(t, b.Logout())
}

func fakeToken() security.SensitiveString {
return security.NewSensitiveString(gofakeit.LetterN(10))
}

func TestWalletConfigOnLoginAccount(t *testing.T) {
utils.Init()
password := "some-password2" // nolint: goconst
tmpdir := t.TempDir()
poktToken := "grove-token" // nolint: goconst
infuraToken := "infura-token" // nolint: goconst
alchemyEthereumMainnetToken := "alchemy-ethereum-mainnet-token"
alchemyEthereumSepoliaToken := "alchemy-ethereum-sepolia-token"
alchemyArbitrumMainnetToken := "alchemy-arbitrum-mainnet-token"
alchemyArbitrumSepoliaToken := "alchemy-arbitrum-sepolia-token"
alchemyOptimismMainnetToken := "alchemy-optimism-mainnet-token"
alchemyOptimismSepoliaToken := "alchemy-optimism-sepolia-token"
raribleMainnetAPIKey := "rarible-mainnet-api-key" // nolint: gosec
raribleTestnetAPIKey := "rarible-testnet-api-key" // nolint: gosec
poktToken := "grove-token" // nolint: goconst
infuraToken := fakeToken()
alchemyEthereumMainnetToken := fakeToken()
alchemyEthereumSepoliaToken := fakeToken()
alchemyArbitrumMainnetToken := fakeToken()
alchemyArbitrumSepoliaToken := fakeToken()
alchemyOptimismMainnetToken := fakeToken()
alchemyOptimismSepoliaToken := fakeToken()
raribleMainnetAPIKey := fakeToken()
raribleTestnetAPIKey := fakeToken()

b := NewGethStatusBackend(tt.MustCreateTestLogger())
createAccountRequest := &requests.CreateAccount{
Expand Down
2 changes: 1 addition & 1 deletion api/default_networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) [
)

appendToken := func(url string) string {
if strings.Contains(url, infura) && request.InfuraToken != "" {
if strings.Contains(url, infura) && !request.InfuraToken.Empty() {
return url + request.InfuraToken
} else if strings.Contains(url, grove) && request.PoktToken != "" {
return url + request.PoktToken
Expand Down
33 changes: 17 additions & 16 deletions api/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/internal/security"
)

const (
Expand Down Expand Up @@ -170,61 +171,61 @@ func SetFleet(fleet string, nodeConfig *params.NodeConfig) error {
func buildWalletConfig(request *requests.WalletSecretsConfig, statusProxyEnabled bool) params.WalletConfig {
walletConfig := params.WalletConfig{
Enabled: true,
AlchemyAPIKeys: make(map[uint64]string),
AlchemyAPIKeys: make(map[uint64]security.SensitiveString),
}

if request.StatusProxyStageName != "" {
walletConfig.StatusProxyStageName = request.StatusProxyStageName
}

if request.OpenseaAPIKey != "" {
if !request.OpenseaAPIKey.Empty() {
walletConfig.OpenseaAPIKey = request.OpenseaAPIKey
}

if request.RaribleMainnetAPIKey != "" {
if !request.RaribleMainnetAPIKey.Empty() {
walletConfig.RaribleMainnetAPIKey = request.RaribleMainnetAPIKey
}

if request.RaribleTestnetAPIKey != "" {
if !request.RaribleTestnetAPIKey.Empty() {
walletConfig.RaribleTestnetAPIKey = request.RaribleTestnetAPIKey
}

if request.InfuraToken != "" {
if !request.InfuraToken.Empty() {
walletConfig.InfuraAPIKey = request.InfuraToken
}

if request.InfuraSecret != "" {
if !request.InfuraSecret.Empty() {
walletConfig.InfuraAPIKeySecret = request.InfuraSecret
}

if request.AlchemyEthereumMainnetToken != "" {
if !request.AlchemyEthereumMainnetToken.Empty() {
walletConfig.AlchemyAPIKeys[mainnetChainID] = request.AlchemyEthereumMainnetToken
}
if request.AlchemyEthereumSepoliaToken != "" {
if !request.AlchemyEthereumSepoliaToken.Empty() {
walletConfig.AlchemyAPIKeys[sepoliaChainID] = request.AlchemyEthereumSepoliaToken
}
if request.AlchemyArbitrumMainnetToken != "" {
if !request.AlchemyArbitrumMainnetToken.Empty() {
walletConfig.AlchemyAPIKeys[arbitrumChainID] = request.AlchemyArbitrumMainnetToken
}
if request.AlchemyArbitrumSepoliaToken != "" {
if !request.AlchemyArbitrumSepoliaToken.Empty() {
walletConfig.AlchemyAPIKeys[arbitrumSepoliaChainID] = request.AlchemyArbitrumSepoliaToken
}
if request.AlchemyOptimismMainnetToken != "" {
if !request.AlchemyOptimismMainnetToken.Empty() {
walletConfig.AlchemyAPIKeys[optimismChainID] = request.AlchemyOptimismMainnetToken
}
if request.AlchemyOptimismSepoliaToken != "" {
if !request.AlchemyOptimismSepoliaToken.Empty() {
walletConfig.AlchemyAPIKeys[optimismSepoliaChainID] = request.AlchemyOptimismSepoliaToken
}
if request.StatusProxyMarketUser != "" {
if !request.StatusProxyMarketUser.Empty() {
walletConfig.StatusProxyMarketUser = request.StatusProxyMarketUser
}
if request.StatusProxyMarketPassword != "" {
if !request.StatusProxyMarketPassword.Empty() {
walletConfig.StatusProxyMarketPassword = request.StatusProxyMarketPassword
}
if request.StatusProxyBlockchainUser != "" {
if !request.StatusProxyBlockchainUser.Empty() {
walletConfig.StatusProxyBlockchainUser = request.StatusProxyBlockchainUser
}
if request.StatusProxyBlockchainPassword != "" {
if !request.StatusProxyBlockchainPassword.Empty() {
walletConfig.StatusProxyBlockchainPassword = request.StatusProxyBlockchainPassword
}

Expand Down
7 changes: 7 additions & 0 deletions internal/security/sensitive_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,10 @@ func TestCopySensitiveString(t *testing.T) {
sCopy := s
require.Equal(t, secretValue, sCopy.Reveal())
}

func TestCopySensitiveString(t *testing.T) {
secretValue := gofakeit.LetterN(10)
s := NewSensitiveString(secretValue)
sCopy := s
require.Equal(t, secretValue, sCopy.Reveal())
}
53 changes: 19 additions & 34 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/status-im/status-go/static"
wakucommon "github.com/status-im/status-go/waku/common"
wakuv2common "github.com/status-im/status-go/wakuv2/common"
"github.com/status-im/status-go/internal/security"
)

// ----------
Expand Down Expand Up @@ -303,10 +304,10 @@ type ProviderConfig struct {

// URL sets the rpc upstream host address for communication with
// a non-local infura endpoint.
User string `json:",omitempty"`
Password string `json:",omitempty"`
APIKey string `json:"APIKey,omitempty"`
APIKeySecret string `json:"APIKeySecret,omitempty"`
User security.SensitiveString `json:",omitempty"`
Password security.SensitiveString `json:",omitempty"`
APIKey security.SensitiveString `json:"APIKey,omitempty"`
APIKeySecret security.SensitiveString `json:"APIKeySecret,omitempty"`
}

// ----------
Expand Down Expand Up @@ -546,36 +547,20 @@ type Network struct {
// WalletConfig extra configuration for wallet.Service.
type WalletConfig struct {
Enabled bool
OpenseaAPIKey string `json:"OpenseaAPIKey"`
RaribleMainnetAPIKey string `json:"RaribleMainnetAPIKey"`
RaribleTestnetAPIKey string `json:"RaribleTestnetAPIKey"`
AlchemyAPIKeys map[uint64]string `json:"AlchemyAPIKeys"`
InfuraAPIKey string `json:"InfuraAPIKey"`
InfuraAPIKeySecret string `json:"InfuraAPIKeySecret"`
StatusProxyMarketUser string `json:"StatusProxyMarketUser"`
StatusProxyMarketPassword string `json:"StatusProxyMarketPassword"`
StatusProxyBlockchainUser string `json:"StatusProxyBlockchainUser"`
StatusProxyBlockchainPassword string `json:"StatusProxyBlockchainPassword"`
StatusProxyEnabled bool `json:"StatusProxyEnabled"`
StatusProxyStageName string `json:"StatusProxyStageName"`
EnableCelerBridge bool `json:"EnableCelerBridge"`
EnableMercuryoProvider bool `json:"EnableMercuryoProvider"`
}

// MarshalJSON custom marshalling to avoid exposing sensitive data in log,
// there's a function called `startNode` will log NodeConfig which include WalletConfig
func (wc WalletConfig) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Enabled bool `json:"Enabled"`
StatusProxyEnabled bool `json:"StatusProxyEnabled"`
EnableCelerBridge bool `json:"EnableCelerBridge"`
EnableMercuryoProvider bool `json:"EnableMercuryoProvider"`
}{
Enabled: wc.Enabled,
StatusProxyEnabled: wc.StatusProxyEnabled,
EnableCelerBridge: wc.EnableCelerBridge,
EnableMercuryoProvider: wc.EnableMercuryoProvider,
})
OpenseaAPIKey security.SensitiveString `json:"OpenseaAPIKey"`
RaribleMainnetAPIKey security.SensitiveString `json:"RaribleMainnetAPIKey"`
RaribleTestnetAPIKey security.SensitiveString `json:"RaribleTestnetAPIKey"`
AlchemyAPIKeys map[uint64]security.SensitiveString `json:"AlchemyAPIKeys"`
InfuraAPIKey security.SensitiveString `json:"InfuraAPIKey"`
InfuraAPIKeySecret security.SensitiveString `json:"InfuraAPIKeySecret"`
StatusProxyMarketUser security.SensitiveString `json:"StatusProxyMarketUser"`
StatusProxyMarketPassword security.SensitiveString `json:"StatusProxyMarketPassword"`
StatusProxyBlockchainUser security.SensitiveString `json:"StatusProxyBlockchainUser"`
StatusProxyBlockchainPassword security.SensitiveString `json:"StatusProxyBlockchainPassword"`
StatusProxyEnabled bool `json:"StatusProxyEnabled"`
StatusProxyStageName string `json:"StatusProxyStageName"`
EnableCelerBridge bool `json:"EnableCelerBridge"`
EnableMercuryoProvider bool `json:"EnableMercuryoProvider"`
}

// LocalNotificationsConfig extra configuration for localnotifications.Service.
Expand Down
6 changes: 4 additions & 2 deletions params/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (

"github.com/status-im/status-go/params"
"github.com/status-im/status-go/t/utils"
"github.com/status-im/status-go/internal/security"
"github.com/brianvoe/gofakeit/v6"
)

func TestNewNodeConfigWithDefaults(t *testing.T) {
Expand Down Expand Up @@ -315,8 +317,8 @@ func TestNodeConfigValidate(t *testing.T) {

func TestMarshalWalletConfigJSON(t *testing.T) {
walletConfig := params.WalletConfig{
OpenseaAPIKey: "some-key",
RaribleMainnetAPIKey: "some-key2",
OpenseaAPIKey: security.NewSensitiveString(gofakeit.LetterN(10)),
RaribleMainnetAPIKey: security.NewSensitiveString(gofakeit.LetterN(10)),
}
bytes, err := json.Marshal(walletConfig)
require.NoError(t, err)
Expand Down
3 changes: 2 additions & 1 deletion protocol/communities/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
_ "github.com/mutecomm/go-sqlcipher/v4" // require go-sqlcipher that overrides default implementation
"github.com/stretchr/testify/suite"
"go.uber.org/zap"
"github.com/status-im/status-go/internal/security"
)

func TestManagerSuite(t *testing.T) {
Expand Down Expand Up @@ -220,7 +221,7 @@ func (s *ManagerSuite) setupManagerForTokenPermissions() (*Manager, *testCollect

options := []ManagerOption{
WithWalletConfig(&params.WalletConfig{
OpenseaAPIKey: "some-key",
OpenseaAPIKey: security.NewSensitiveString("some-key"),
}),
WithCollectiblesManager(cm),
WithTokenManager(tm),
Expand Down
39 changes: 20 additions & 19 deletions protocol/requests/create_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

utils "github.com/status-im/status-go/common"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/internal/security"
)

var ErrCreateAccountInvalidDisplayName = errors.New("create-account: invalid display name")
Expand Down Expand Up @@ -89,25 +90,25 @@ type CreateAccount struct {
}

type WalletSecretsConfig struct {
PoktToken string `json:"poktToken"`
InfuraToken string `json:"infuraToken"`
InfuraSecret string `json:"infuraSecret"`
OpenseaAPIKey string `json:"openseaApiKey"`
RaribleMainnetAPIKey string `json:"raribleMainnetApiKey"`
RaribleTestnetAPIKey string `json:"raribleTestnetApiKey"`

AlchemyEthereumMainnetToken string `json:"alchemyEthereumMainnetToken"`
AlchemyEthereumSepoliaToken string `json:"alchemyEthereumSepoliaToken"`
AlchemyArbitrumMainnetToken string `json:"alchemyArbitrumMainnetToken"`
AlchemyArbitrumSepoliaToken string `json:"alchemyArbitrumSepoliaToken"`
AlchemyOptimismMainnetToken string `json:"alchemyOptimismMainnetToken"`
AlchemyOptimismSepoliaToken string `json:"alchemyOptimismSepoliaToken"`

StatusProxyStageName string `json:"statusProxyStageName"`
StatusProxyMarketUser string `json:"statusProxyMarketUser"`
StatusProxyMarketPassword string `json:"statusProxyMarketPassword"`
StatusProxyBlockchainUser string `json:"statusProxyBlockchainUser"`
StatusProxyBlockchainPassword string `json:"statusProxyBlockchainPassword"`
PoktToken string `json:"poktToken"`
InfuraToken security.SensitiveString `json:"infuraToken"`
InfuraSecret security.SensitiveString `json:"infuraSecret"`
OpenseaAPIKey security.SensitiveString `json:"openseaApiKey"`
RaribleMainnetAPIKey security.SensitiveString `json:"raribleMainnetApiKey"`
RaribleTestnetAPIKey security.SensitiveString `json:"raribleTestnetApiKey"`

AlchemyEthereumMainnetToken security.SensitiveString `json:"alchemyEthereumMainnetToken"`
AlchemyEthereumSepoliaToken security.SensitiveString `json:"alchemyEthereumSepoliaToken"`
AlchemyArbitrumMainnetToken security.SensitiveString `json:"alchemyArbitrumMainnetToken"`
AlchemyArbitrumSepoliaToken security.SensitiveString `json:"alchemyArbitrumSepoliaToken"`
AlchemyOptimismMainnetToken security.SensitiveString `json:"alchemyOptimismMainnetToken"`
AlchemyOptimismSepoliaToken security.SensitiveString `json:"alchemyOptimismSepoliaToken"`

StatusProxyStageName string `json:"statusProxyStageName"`
StatusProxyMarketUser security.SensitiveString `json:"statusProxyMarketUser"`
StatusProxyMarketPassword security.SensitiveString `json:"statusProxyMarketPassword"`
StatusProxyBlockchainUser security.SensitiveString `json:"statusProxyBlockchainUser"`
StatusProxyBlockchainPassword security.SensitiveString `json:"statusProxyBlockchainPassword"`

// Testing
GanacheURL string `json:"ganacheURL"`
Expand Down
2 changes: 1 addition & 1 deletion rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ func (c *Client) getEthClients(network *params.Network) []ethclient.RPSLimitedEt
// For now, we only support auth for status-proxy.
var opts []gethrpc.ClientOption
if provider.authenticationNeeded() {
authEncoded := base64.StdEncoding.EncodeToString([]byte(provider.Auth))
authEncoded := base64.StdEncoding.EncodeToString([]byte(provider.Auth.Reveal()))
opts = append(opts,
gethrpc.WithHeaders(http.Header{
"Authorization": {"Basic " + authEncoded},
Expand Down
13 changes: 7 additions & 6 deletions rpc/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"go.uber.org/zap"

"github.com/status-im/status-go/params"
"github.com/status-im/status-go/internal/security"
)

const (
Expand All @@ -21,12 +22,12 @@ const (
type Provider struct {
Key string
URL string
Auth string
Auth security.SensitiveString
Priority int
}

func (p Provider) authenticationNeeded() bool {
return len(p.Auth) > 0
return !p.Auth.Empty()
}

func getProviderPriorityByURL(url string) int {
Expand Down Expand Up @@ -58,7 +59,7 @@ func getProviderConfig(providerConfigs []params.ProviderConfig, providerName str
return params.ProviderConfig{}, fmt.Errorf("provider config not found for provider: %s", providerName)
}

func createProvider(key, url, credentials string, providers *[]Provider) {
func createProvider(key, url string, credentials security.SensitiveString, providers *[]Provider) {
priority := getProviderPriorityByURL(url)
*providers = append(*providers, Provider{
Key: key,
Expand All @@ -78,12 +79,12 @@ func (c *Client) prepareProviders(network *params.Network) []Provider {
}

// Add main and fallback providers
createProvider(ProviderMain, network.RPCURL, "", &providers)
createProvider(ProviderFallback, network.FallbackURL, "", &providers)
createProvider(ProviderMain, network.RPCURL, security.NewSensitiveString(""), &providers)
createProvider(ProviderFallback, network.FallbackURL, security.NewSensitiveString(""), &providers)

// If the proxy provider is enabled, add it and its fallback options
if proxyProvider.Enabled {
credentials := proxyProvider.User + ":" + proxyProvider.Password
credentials := security.NewSensitiveString(proxyProvider.User.Reveal() + ":" + proxyProvider.Password.Reveal())
createProvider(ProviderStatusProxy, network.DefaultRPCURL, credentials, &providers)
createProvider(ProviderStatusProxyFallback, network.DefaultFallbackURL, credentials, &providers)
createProvider(ProviderStatusProxyFallback2, network.DefaultFallbackURL2, credentials, &providers)
Expand Down
Loading

0 comments on commit cdf9304

Please sign in to comment.