/**
* Copyright 2012 multibit.org
*
* Licensed under the MIT license (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://opensource.org/licenses/mit-license.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.multibit.viewsystem.swing.action;
import com.google.bitcoin.core.Wallet;
import com.google.bitcoin.crypto.KeyCrypterException;
import org.multibit.controller.bitcoin.BitcoinController;
import org.multibit.file.BackupManager;
import org.multibit.file.FileHandler;
import org.multibit.model.bitcoin.WalletBusyListener;
import org.multibit.model.bitcoin.WalletData;
import org.multibit.model.bitcoin.WalletInfoData;
import org.multibit.store.MultiBitWalletVersion;
import org.multibit.viewsystem.swing.MultiBitFrame;
import org.multibit.viewsystem.swing.view.panels.RemovePasswordPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.nio.CharBuffer;
/**
* This {@link Action} action removes the encryption of private keys in a wallet.
*/
public class RemovePasswordSubmitAction extends MultiBitSubmitAction implements WalletBusyListener {
private static final Logger log = LoggerFactory.getLogger(RemovePasswordSubmitAction.class);
private static final long serialVersionUID = 1923492460598757765L;
private RemovePasswordPanel removePasswordPanel;
private JPasswordField password1;
/**
* Creates a new {@link RemovePasswordSubmitAction}.
*/
public RemovePasswordSubmitAction(BitcoinController bitcoinController, RemovePasswordPanel removePasswordPanel,
ImageIcon icon, JPasswordField password1, MultiBitFrame mainFrame) {
super(bitcoinController, "removePasswordSubmitAction.text", "removePasswordSubmitAction.tooltip", "removePasswordSubmitAction.mnemonicKey", icon);
this.removePasswordPanel = removePasswordPanel;
this.password1 = password1;
// This action is a WalletBusyListener.
super.bitcoinController.registerWalletBusyListener(this);
walletBusyChange(super.bitcoinController.getModel().getActivePerWalletModelData().isBusy());
}
/**
* Remove the password protection on a wallet.
*/
@Override
public void actionPerformed(ActionEvent e) {
removePasswordPanel.clearMessages();
char[] passwordToUse = password1.getPassword();
// Get the passwords on the password fields.
if (password1.getPassword() == null || password1.getPassword().length == 0) {
// Notify that the user must enter a password.
removePasswordPanel.setMessage1(controller.getLocaliser()
.getString("removePasswordPanel.enterPassword"));
return;
}
if (super.bitcoinController.getModel().getActiveWallet() != null) {
Wallet wallet = super.bitcoinController.getModel().getActiveWallet();
if (wallet != null) {
WalletData perWalletModelData = null;
WalletInfoData walletInfoData = null;
try {
// Double check wallet is not busy then declare that the active
// wallet is busy with the task
perWalletModelData = super.bitcoinController.getModel().getActivePerWalletModelData();
walletInfoData = super.bitcoinController.getModel().getActiveWalletWalletInfo();
if (!perWalletModelData.isBusy()) {
perWalletModelData.setBusy(true);
perWalletModelData.setBusyTaskKey("removePasswordSubmitAction.text");
super.bitcoinController.fireWalletBusyChange(true);
wallet.decrypt(wallet.getKeyCrypter().deriveKey(CharBuffer.wrap(passwordToUse)));
walletInfoData.setWalletVersion(MultiBitWalletVersion.PROTOBUF);
perWalletModelData.setDirty(true);
FileHandler fileHandler = new FileHandler(super.bitcoinController);
fileHandler.savePerWalletModelData(perWalletModelData, true);
// Backup the wallet and wallet info.
BackupManager.INSTANCE.backupPerWalletModelData(fileHandler, perWalletModelData);
}
} catch (KeyCrypterException kce) {
removePasswordPanel.setMessage1(controller.getLocaliser()
.getString("removePasswordPanel.removePasswordFailed", new String[]{kce.getMessage()}));
return;
} finally {
// Declare that wallet is no longer busy with the task.
if (perWalletModelData != null) {
perWalletModelData.setBusyTaskKey(null);
perWalletModelData.setBusy(false);
}
super.bitcoinController.fireWalletBusyChange(false);
}
}
}
controller.fireDataChangedUpdateNow();
// Success.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
removePasswordPanel.clearMessages();
removePasswordPanel.clearPasswords();
removePasswordPanel.setMessage1(controller.getLocaliser()
.getString("removePasswordPanel.removePasswordSuccess"));
}});
}
@Override
public void walletBusyChange(boolean newWalletIsBusy) {
// Update the enable status of the action to match the wallet busy status.
if (super.bitcoinController.getModel().getActivePerWalletModelData().isBusy()) {
// Wallet is busy with another operation that may change the private keys - Action is disabled.
putValue(SHORT_DESCRIPTION, controller.getLocaliser().getString("multiBitSubmitAction.walletIsBusy",
new Object[]{controller.getLocaliser().getString(this.bitcoinController.getModel().getActivePerWalletModelData().getBusyTaskKey())}));
} else {
// Enable
putValue(SHORT_DESCRIPTION, controller.getLocaliser().getString("removePasswordSubmitAction.text"));
}
}
}