Merge pull request #6979 from alvasw/FilterManagerMockedPrivilegeKeysTests

Add FilterManagerMockedPrivilegeKeysTests
This commit is contained in:
Alejandro García 2023-12-31 13:45:13 +00:00 committed by GitHub
commit f12069aeeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 210 additions and 29 deletions

View File

@ -17,6 +17,7 @@
package bisq.apitest;
import bisq.common.app.DevEnv;
import bisq.common.config.BisqHelpFormatter;
import bisq.common.util.Utilities;
@ -45,7 +46,6 @@ import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.ApiTestConfig.MEDIATOR;
import static bisq.apitest.config.ApiTestConfig.REFUND_AGENT;
import static bisq.apitest.config.BisqAppConfig.*;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static java.lang.String.format;
import static java.lang.System.exit;
import static java.lang.System.out;
@ -482,8 +482,8 @@ public class Scaffold {
GrpcClient arbClient = new GrpcClient(getLoopbackAddress().getHostAddress(),
arbdaemon.apiPort,
config.apiPassword);
arbClient.registerDisputeAgent(MEDIATOR, DEV_PRIVILEGE_PRIV_KEY);
arbClient.registerDisputeAgent(REFUND_AGENT, DEV_PRIVILEGE_PRIV_KEY);
arbClient.registerDisputeAgent(MEDIATOR, DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
arbClient.registerDisputeAgent(REFUND_AGENT, DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
}
}
}

View File

@ -17,6 +17,8 @@
package bisq.apitest.method;
import bisq.common.app.DevEnv;
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
@ -34,7 +36,6 @@ import static bisq.apitest.config.ApiTestConfig.MEDIATOR;
import static bisq.apitest.config.ApiTestConfig.REFUND_AGENT;
import static bisq.apitest.config.BisqAppConfig.arbdaemon;
import static bisq.apitest.config.BisqAppConfig.seednode;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
@ -60,7 +61,7 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Order(1)
public void testRegisterArbitratorShouldThrowException() {
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
arbClient.registerDisputeAgent(ARBITRATOR, DEV_PRIVILEGE_PRIV_KEY));
arbClient.registerDisputeAgent(ARBITRATOR, DevEnv.getDEV_PRIVILEGE_PRIV_KEY()));
assertEquals("UNIMPLEMENTED: arbitrators must be registered in a Bisq UI",
exception.getMessage());
}
@ -69,7 +70,7 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Order(2)
public void testInvalidDisputeAgentTypeArgShouldThrowException() {
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
arbClient.registerDisputeAgent("badagent", DEV_PRIVILEGE_PRIV_KEY));
arbClient.registerDisputeAgent("badagent", DevEnv.getDEV_PRIVILEGE_PRIV_KEY()));
assertEquals("INVALID_ARGUMENT: unknown dispute agent type 'badagent'",
exception.getMessage());
}
@ -78,7 +79,7 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Order(3)
public void testInvalidRegistrationKeyArgShouldThrowException() {
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
arbClient.registerDisputeAgent(REFUND_AGENT, "invalid" + DEV_PRIVILEGE_PRIV_KEY));
arbClient.registerDisputeAgent(REFUND_AGENT, "invalid" + DevEnv.getDEV_PRIVILEGE_PRIV_KEY()));
assertEquals("INVALID_ARGUMENT: invalid registration key",
exception.getMessage());
}
@ -86,13 +87,13 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Test
@Order(4)
public void testRegisterMediator() {
arbClient.registerDisputeAgent(MEDIATOR, DEV_PRIVILEGE_PRIV_KEY);
arbClient.registerDisputeAgent(MEDIATOR, DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
}
@Test
@Order(5)
public void testRegisterRefundAgent() {
arbClient.registerDisputeAgent(REFUND_AGENT, DEV_PRIVILEGE_PRIV_KEY);
arbClient.registerDisputeAgent(REFUND_AGENT, DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
}
@AfterAll

View File

@ -19,6 +19,10 @@ package bisq.common.app;
import bisq.common.config.Config;
import java.util.Collections;
import java.util.List;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -29,8 +33,14 @@ public class DevEnv {
// peer (click user icon and alt+r), filter/block offers by various data like offer ID (cmd + f).
// The user can set a program argument to ignore all of those privileged network_messages. They are intended for
// emergency cases only (beside update message and arbitrator registration).
public static final String DEV_PRIVILEGE_PUB_KEY = "027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee";
public static final String DEV_PRIVILEGE_PRIV_KEY = "6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a";
@Getter
private static final String DEV_PRIVILEGE_PUB_KEY = "027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee";
@Getter
private static final String DEV_PRIVILEGE_PRIV_KEY = "6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a";
public static List<String> getDevPrivilegePubKeys() {
return Collections.singletonList(DEV_PRIVILEGE_PUB_KEY);
}
public static void setup(Config config) {
DevEnv.setDevMode(config.useDevMode);

View File

@ -105,7 +105,7 @@ public class AlertManager {
});
}
pubKeyAsHex = useDevPrivilegeKeys ?
DevEnv.DEV_PRIVILEGE_PUB_KEY :
DevEnv.getDEV_PRIVILEGE_PUB_KEY() :
"036d8a1dfcb406886037d2381da006358722823e1940acc2598c844bbc0fd1026f";
}

View File

@ -106,7 +106,7 @@ public class PrivateNotificationManager implements MessageListener {
this.mailboxMessageService.addDecryptedMailboxListener(this::handleMessage);
}
pubKeyAsHex = useDevPrivilegeKeys ?
DevEnv.DEV_PRIVILEGE_PUB_KEY :
DevEnv.getDEV_PRIVILEGE_PUB_KEY() :
"02ba7c5de295adfe57b60029f3637a2c6b1d0e969a8aaefb9e0ddc3a7963f26925";
}

View File

@ -27,6 +27,7 @@ import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.common.app.DevEnv;
import bisq.common.config.Config;
import bisq.common.crypto.KeyRing;
@ -42,7 +43,6 @@ import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static bisq.core.support.SupportType.ARBITRATION;
import static bisq.core.support.SupportType.MEDIATION;
import static bisq.core.support.SupportType.REFUND;
@ -87,7 +87,7 @@ class CoreDisputeAgentsService {
|| !config.useLocalhostForP2P)
throw new UnsupportedOperationException("dispute agents must be registered in a Bisq UI");
if (!registrationKey.equals(DEV_PRIVILEGE_PRIV_KEY))
if (!registrationKey.equals(DevEnv.getDEV_PRIVILEGE_PRIV_KEY()))
throw new IllegalArgumentException("invalid registration key");
Optional<SupportType> supportType = getSupportType(disputeAgentType);

View File

@ -108,7 +108,7 @@ public abstract class AccountingNode implements DaoSetupService, DaoStateListene
}
private static Set<String> getPermittedPubKeys(boolean useDevPrivilegeKeys) {
return useDevPrivilegeKeys ? Set.of(DevEnv.DEV_PRIVILEGE_PUB_KEY) : PERMITTED_PUB_KEYS;
return useDevPrivilegeKeys ? Set.of(DevEnv.getDEV_PRIVILEGE_PUB_KEY()) : PERMITTED_PUB_KEYS;
}

View File

@ -92,8 +92,8 @@ public class AccountingFullNodeNetworkService implements MessageListener, PeerMa
this.useDevPrivilegeKeys = useDevPrivilegeKeys;
if (useDevPrivilegeKeys) {
bmOracleNodePubKey = DevEnv.DEV_PRIVILEGE_PUB_KEY;
bmOracleNodePrivKey = DevEnv.DEV_PRIVILEGE_PRIV_KEY;
bmOracleNodePubKey = DevEnv.getDEV_PRIVILEGE_PUB_KEY();
bmOracleNodePrivKey = DevEnv.getDEV_PRIVILEGE_PRIV_KEY();
}
this.bmOracleNodePubKey = bmOracleNodePubKey.isEmpty() ? null : bmOracleNodePubKey;
this.bmOracleNodePrivKey = bmOracleNodePrivKey.isEmpty() ? null : toEcKey(bmOracleNodePrivKey);

View File

@ -133,7 +133,7 @@ public class FilterManager {
this.ignoreDevMsg = ignoreDevMsg;
publicKeys = useDevPrivilegeKeys ?
Collections.singletonList(DevEnv.DEV_PRIVILEGE_PUB_KEY) :
DevEnv.getDevPrivilegePubKeys() :
List.of("0358d47858acdc41910325fce266571540681ef83a0d6fedce312bef9810793a27",
"029340c3e7d4bb0f9e651b5f590b434fecb6175aeaa57145c7804ff05d210e534f",
"034dc7530bf66ffd9580aa98031ea9a18ac2d269f7c56c0e71eca06105b9ed69f9");

View File

@ -100,7 +100,7 @@ public abstract class DisputeAgentManager<T extends DisputeAgent> {
this.disputeAgentService = disputeAgentService;
this.user = user;
this.filterManager = filterManager;
publicKeys = useDevPrivilegeKeys ? Collections.singletonList(DevEnv.DEV_PRIVILEGE_PUB_KEY) : getPubKeyList();
publicKeys = useDevPrivilegeKeys ? Collections.singletonList(DevEnv.getDEV_PRIVILEGE_PUB_KEY()) : getPubKeyList();
}
@ -193,7 +193,7 @@ public abstract class DisputeAgentManager<T extends DisputeAgent> {
String pubKeyAsHex = Utils.HEX.encode(e.getRegistrationPubKey());
boolean isInPublicKeyInList = isPublicKeyInList(pubKeyAsHex);
if (!isInPublicKeyInList) {
if (DevEnv.DEV_PRIVILEGE_PUB_KEY.equals(pubKeyAsHex))
if (DevEnv.getDEV_PRIVILEGE_PUB_KEY().equals(pubKeyAsHex))
log.info("We got the DEV_PRIVILEGE_PUB_KEY in our list of publicKeys. RegistrationPubKey={}, nodeAddress={}",
Utilities.bytesAsHexString(e.getRegistrationPubKey()),
e.getNodeAddress().getFullAddress());

View File

@ -63,7 +63,7 @@ public abstract class DisputeAgentService<T extends DisputeAgent> {
ErrorMessageHandler errorMessageHandler) {
log.debug("addDisputeAgent disputeAgent.hashCode() " + disputeAgent.hashCode());
if (!Config.baseCurrencyNetwork().isMainnet() ||
!Utilities.encodeToHex(disputeAgent.getRegistrationPubKey()).equals(DevEnv.DEV_PRIVILEGE_PUB_KEY)) {
!Utilities.encodeToHex(disputeAgent.getRegistrationPubKey()).equals(DevEnv.getDEV_PRIVILEGE_PUB_KEY())) {
boolean result = p2PService.addProtectedStorageEntry(disputeAgent);
if (result) {
log.trace("Add disputeAgent to network was successful. DisputeAgent.hashCode() = {}", disputeAgent.hashCode());

View File

@ -85,7 +85,7 @@ public class FilterManagerAddFilterToNetworkTests {
KeyPair ownerKeyPair = keyPairGenerator.generateKeyPair();
ownerPublicKey = ownerKeyPair.getPublic();
privilegedDevEcKey = ECKey.fromPrivate(new BigInteger(1, HEX.decode(DevEnv.DEV_PRIVILEGE_PRIV_KEY)));
privilegedDevEcKey = ECKey.fromPrivate(new BigInteger(1, HEX.decode(DevEnv.getDEV_PRIVILEGE_PRIV_KEY())));
privilegedDevPubKeyHex = HEX.encode(privilegedDevEcKey.getPubKey());
}

View File

@ -0,0 +1,164 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq 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 Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.filter;
import bisq.core.provider.ProvidersRepository;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.network.BanFilter;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.ProtectedStorageEntry;
import bisq.common.app.DevEnv;
import bisq.common.config.Config;
import bisq.common.crypto.KeyRing;
import bisq.common.crypto.Sig;
import org.bitcoinj.core.ECKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Security;
import java.nio.file.Path;
import java.io.File;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import static org.bitcoinj.core.Utils.HEX;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
public class FilterManagerMockedPrivilegeKeysTests {
static {
Security.addProvider(new BouncyCastleProvider());
}
private final PublicKey ownerPublicKey;
private final ECKey privilegedDevEcKey;
private final ECKey secondPrivilegedDevEcKey;
public FilterManagerMockedPrivilegeKeysTests() throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(Sig.KEY_ALGO, "BC");
KeyPair ownerKeyPair = keyPairGenerator.generateKeyPair();
ownerPublicKey = ownerKeyPair.getPublic();
privilegedDevEcKey = ECKey.fromPrivate(new BigInteger(1, HEX.decode(DevEnv.getDEV_PRIVILEGE_PRIV_KEY())));
secondPrivilegedDevEcKey = new ECKey();
}
@Test
void testBannedPrivilegedDevKey(@TempDir Path tmpDir,
@Mock P2PService p2PService,
@Mock P2PDataStorage p2pDataStorage) {
try (MockedStatic<DevEnv> devEnv = Mockito.mockStatic(DevEnv.class)) {
String privilegedDevPubKeyHex = HEX.encode(privilegedDevEcKey.getPubKey());
String secondPrivilegedDevPubKeyHex = HEX.encode(secondPrivilegedDevEcKey.getPubKey());
devEnv.when(DevEnv::getDevPrivilegePubKeys)
.thenReturn(List.of(privilegedDevPubKeyHex, secondPrivilegedDevPubKeyHex));
Config config = mock(Config.class);
File configFile = tmpDir.resolve("configFile").toFile();
doReturn(configFile).when(config).getConfigFile();
FilterManager filterManager = new FilterManager(
p2PService,
mock(KeyRing.class),
mock(User.class),
mock(Preferences.class),
config,
mock(ProvidersRepository.class),
mock(BanFilter.class),
false,
true
);
doReturn(p2pDataStorage).when(p2PService).getP2PDataStorage();
Map<P2PDataStorage.ByteArray, ProtectedStorageEntry> p2pStorageMap = new HashMap<>();
doReturn(p2pStorageMap).when(p2pDataStorage).getMap();
// No filter before adding our filter
assertNull(filterManager.getFilter());
long creationTime = System.currentTimeMillis();
List<String> bannedPrivilegedDevKey = List.of(secondPrivilegedDevPubKeyHex);
Filter firstFilter = TestFilter.createFilter(ownerPublicKey, privilegedDevPubKeyHex,
creationTime, bannedPrivilegedDevKey);
Filter firstFilterWithSig = TestFilter.signFilter(firstFilter, privilegedDevEcKey);
Filter secondFilterWithSig = TestFilter.createSignedFilter(ownerPublicKey, secondPrivilegedDevEcKey,
creationTime + 100);
assertNotEquals(firstFilterWithSig, secondFilterWithSig);
p2pStorageMap.put(
new P2PDataStorage.ByteArray(new byte[100]),
TestFilter.createProtectedStorageEntryForFilter(firstFilterWithSig)
);
filterManager.onAllServicesInitialized();
// Our filter got set
Filter currentFilter = filterManager.getFilter();
assertNotNull(currentFilter);
assertEquals(firstFilterWithSig, currentFilter);
p2pStorageMap.clear();
p2pStorageMap.put(
new P2PDataStorage.ByteArray(new byte[100]),
TestFilter.createProtectedStorageEntryForFilter(secondFilterWithSig)
);
filterManager.onAllServicesInitialized();
// Our filter got set
currentFilter = filterManager.getFilter();
assertNotNull(currentFilter);
assertEquals(firstFilterWithSig, currentFilter);
}
}
}

View File

@ -31,6 +31,7 @@ import java.time.Clock;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import static org.bitcoinj.core.Utils.HEX;
@ -60,6 +61,11 @@ public class TestFilter {
}
public static Filter createFilter(PublicKey ownerPublicKey, String signerPubKeyAsHex, long creationDate) {
return createFilter(ownerPublicKey, signerPubKeyAsHex, creationDate, Collections.emptyList());
}
public static Filter createFilter(PublicKey ownerPublicKey, String signerPubKeyAsHex,
long creationDate, List<String> bannedDevKeys) {
return new Filter(
Collections.emptyList(),
Collections.emptyList(),
@ -83,7 +89,7 @@ public class TestFilter {
null,
null,
signerPubKeyAsHex,
Collections.emptyList(),
bannedDevKeys,
false,
Collections.emptyList(),
Collections.emptySet(),
@ -100,7 +106,7 @@ public class TestFilter {
);
}
private static Filter signFilter(Filter unsignedFilter, ECKey signerKey) {
public static Filter signFilter(Filter unsignedFilter, ECKey signerKey) {
byte[] filterData = unsignedFilter.toProtoMessage().toByteArray();
Sha256Hash hash = Sha256Hash.of(filterData);

View File

@ -130,7 +130,7 @@ public class FilterWindow extends Overlay<FilterWindow> {
InputTextField keyTF = addInputTextField(gridPane, ++rowIndex,
Res.get("shared.unlock"), 10);
if (useDevPrivilegeKeys) {
keyTF.setText(DevEnv.DEV_PRIVILEGE_PRIV_KEY);
keyTF.setText(DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
}
InputTextField offerIdsTF = addInputTextField(gridPane, ++rowIndex,

View File

@ -102,7 +102,7 @@ public class SendAlertMessageWindow extends Overlay<SendAlertMessageWindow> {
InputTextField keyInputTextField = addInputTextField(gridPane, ++rowIndex,
Res.get("shared.unlock"), 10);
if (useDevPrivilegeKeys)
keyInputTextField.setText(DevEnv.DEV_PRIVILEGE_PRIV_KEY);
keyInputTextField.setText(DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
Tuple2<Label, TextArea> labelTextAreaTuple2 = addTopLabelTextArea(gridPane, ++rowIndex,
Res.get("sendAlertMessageWindow.alertMsg"),

View File

@ -99,7 +99,7 @@ public class SendPrivateNotificationWindow extends Overlay<SendPrivateNotificati
private void addContent() {
InputTextField keyInputTextField = addInputTextField(gridPane, ++rowIndex, Res.get("shared.unlock"), 10);
if (useDevPrivilegeKeys)
keyInputTextField.setText(DevEnv.DEV_PRIVILEGE_PRIV_KEY);
keyInputTextField.setText(DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
Tuple2<Label, TextArea> labelTextAreaTuple2 = addTopLabelTextArea(gridPane, ++rowIndex,
Res.get("sendPrivateNotificationWindow.privateNotification"),

View File

@ -120,7 +120,7 @@ public class UnlockDisputeAgentRegistrationWindow extends Overlay<UnlockDisputeA
keyInputTextField = labelInputTextFieldTuple2.second;
if (useDevPrivilegeKeys)
keyInputTextField.setText(DevEnv.DEV_PRIVILEGE_PRIV_KEY);
keyInputTextField.setText(DevEnv.getDEV_PRIVILEGE_PRIV_KEY());
changeListener = (observable, oldValue, newValue) -> unlockButton.setDisable(newValue.length() == 0);
keyInputTextField.textProperty().addListener(changeListener);
}