Refactor Profiles
This commit is contained in:
@@ -59,12 +59,10 @@ class ProfilePanel extends JPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final String loginText;
|
private final String loginText;
|
||||||
private final ProfilesPanel parent;
|
|
||||||
private String password = null;
|
private String password = null;
|
||||||
|
|
||||||
ProfilePanel(final Client client, String data, ProfilesConfig config, ProfilesPanel parent)
|
ProfilePanel(final Client client, String data, ProfilesConfig config, ProfilesPanel parent)
|
||||||
{
|
{
|
||||||
this.parent = parent;
|
|
||||||
String[] parts = data.split(":");
|
String[] parts = data.split(":");
|
||||||
this.loginText = parts[1];
|
this.loginText = parts[1];
|
||||||
if (parts.length == 3)
|
if (parts.length == 3)
|
||||||
|
|||||||
+7
-9
@@ -31,8 +31,6 @@ import net.runelite.client.config.ConfigItem;
|
|||||||
@ConfigGroup("profiles")
|
@ConfigGroup("profiles")
|
||||||
public interface ProfilesConfig extends Config
|
public interface ProfilesConfig extends Config
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "profilesData",
|
keyName = "profilesData",
|
||||||
name = "",
|
name = "",
|
||||||
@@ -52,10 +50,10 @@ public interface ProfilesConfig extends Config
|
|||||||
void profilesData(String str);
|
void profilesData(String str);
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "salt",
|
keyName = "salt",
|
||||||
name = "",
|
name = "",
|
||||||
description = "",
|
description = "",
|
||||||
hidden = true
|
hidden = true
|
||||||
)
|
)
|
||||||
default String salt()
|
default String salt()
|
||||||
{
|
{
|
||||||
@@ -63,9 +61,9 @@ public interface ProfilesConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "salt",
|
keyName = "salt",
|
||||||
name = "",
|
name = "",
|
||||||
description = ""
|
description = ""
|
||||||
)
|
)
|
||||||
void salt(String key);
|
void salt(String key);
|
||||||
|
|
||||||
|
|||||||
+42
-37
@@ -51,9 +51,14 @@ import javax.crypto.SecretKeyFactory;
|
|||||||
import javax.crypto.spec.PBEKeySpec;
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.swing.*;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JPasswordField;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.client.ui.ColorScheme;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
@@ -71,7 +76,7 @@ class ProfilesPanel extends PluginPanel
|
|||||||
private static final String PASSWORD_LABEL = "Account Password";
|
private static final String PASSWORD_LABEL = "Account Password";
|
||||||
private static final String HELP = "To add and load accounts, first enter a password into the Encryption Password " +
|
private static final String HELP = "To add and load accounts, first enter a password into the Encryption Password " +
|
||||||
"field then press Load Accounts. You can now add as many accounts as you would like. The next time you restart" +
|
"field then press Load Accounts. You can now add as many accounts as you would like. The next time you restart" +
|
||||||
" Runelite, enter your encryption password and click load accounts to see the accounts you entered";
|
"Runelite, enter your encryption password and click load accounts to see the accounts you entered";
|
||||||
private static final Dimension PREFERRED_SIZE = new Dimension(PluginPanel.PANEL_WIDTH - 20, 30);
|
private static final Dimension PREFERRED_SIZE = new Dimension(PluginPanel.PANEL_WIDTH - 20, 30);
|
||||||
private static final Dimension HELP_PREFERRED_SIZE = new Dimension(PluginPanel.PANEL_WIDTH - 20, 130);
|
private static final Dimension HELP_PREFERRED_SIZE = new Dimension(PluginPanel.PANEL_WIDTH - 20, 130);
|
||||||
|
|
||||||
@@ -81,12 +86,10 @@ class ProfilesPanel extends PluginPanel
|
|||||||
private static ProfilesConfig profilesConfig;
|
private static ProfilesConfig profilesConfig;
|
||||||
|
|
||||||
private final JPasswordField txtDecryptPassword = new JPasswordField(UNLOCK_PASSWORD);
|
private final JPasswordField txtDecryptPassword = new JPasswordField(UNLOCK_PASSWORD);
|
||||||
private final JButton btnLoadAccounts = new JButton(LOAD_ACCOUNTS);
|
|
||||||
private final JTextField txtAccountLabel = new JTextField(ACCOUNT_LABEL);
|
private final JTextField txtAccountLabel = new JTextField(ACCOUNT_LABEL);
|
||||||
private final JPasswordField txtAccountLogin = new JPasswordField(ACCOUNT_USERNAME);
|
private final JPasswordField txtAccountLogin = new JPasswordField(ACCOUNT_USERNAME);
|
||||||
private final JPasswordField txtPasswordLogin = new JPasswordField(PASSWORD_LABEL);
|
private final JPasswordField txtPasswordLogin = new JPasswordField(PASSWORD_LABEL);
|
||||||
private final JPanel profilesPanel = new JPanel();
|
private final JPanel profilesPanel = new JPanel();
|
||||||
private final JPanel helpPanel = new JPanel(new BorderLayout());
|
|
||||||
private GridBagConstraints c;
|
private GridBagConstraints c;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -108,18 +111,18 @@ class ProfilesPanel extends PluginPanel
|
|||||||
c.weighty = 0;
|
c.weighty = 0;
|
||||||
c.insets = new Insets(0, 0, 4, 0);
|
c.insets = new Insets(0, 0, 4, 0);
|
||||||
|
|
||||||
|
JPanel helpPanel = new JPanel(new BorderLayout());
|
||||||
helpPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
helpPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
JLabel helpLabel = new JLabel("<html> <p>" + HELP + "</p></html>");
|
JLabel helpLabel = new JLabel("<html> <p>" + HELP + "</p></html>");
|
||||||
helpLabel.setFont(FontManager.getRunescapeSmallFont());
|
helpLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
helpPanel.setPreferredSize(HELP_PREFERRED_SIZE);
|
helpPanel.setPreferredSize(HELP_PREFERRED_SIZE);
|
||||||
//helpPanel.setSize(MINIMUM_SIZE);
|
// helpPanel.setSize(MINIMUM_SIZE);
|
||||||
helpPanel.add(helpLabel, BorderLayout.NORTH);
|
helpPanel.add(helpLabel, BorderLayout.NORTH);
|
||||||
|
|
||||||
add(helpPanel);
|
add(helpPanel);
|
||||||
c.gridy = c.gridy + 3;
|
c.gridy = c.gridy + 3;
|
||||||
c.gridy++;
|
c.gridy++;
|
||||||
|
|
||||||
|
|
||||||
txtDecryptPassword.setEchoChar((char) 0);
|
txtDecryptPassword.setEchoChar((char) 0);
|
||||||
txtDecryptPassword.setPreferredSize(PREFERRED_SIZE);
|
txtDecryptPassword.setPreferredSize(PREFERRED_SIZE);
|
||||||
txtDecryptPassword.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
txtDecryptPassword.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||||
@@ -154,6 +157,7 @@ class ProfilesPanel extends PluginPanel
|
|||||||
add(txtDecryptPassword, c);
|
add(txtDecryptPassword, c);
|
||||||
c.gridy++;
|
c.gridy++;
|
||||||
|
|
||||||
|
JButton btnLoadAccounts = new JButton(LOAD_ACCOUNTS);
|
||||||
btnLoadAccounts.setPreferredSize(PREFERRED_SIZE);
|
btnLoadAccounts.setPreferredSize(PREFERRED_SIZE);
|
||||||
btnLoadAccounts.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
btnLoadAccounts.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
btnLoadAccounts.setMinimumSize(MINIMUM_SIZE);
|
btnLoadAccounts.setMinimumSize(MINIMUM_SIZE);
|
||||||
@@ -333,7 +337,7 @@ class ProfilesPanel extends PluginPanel
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(!addProfile(data))
|
if (!addProfile(data))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -410,10 +414,10 @@ class ProfilesPanel extends PluginPanel
|
|||||||
c.gridy = 0;
|
c.gridy = 0;
|
||||||
c.insets = new Insets(0, 0, 5, 0);
|
c.insets = new Insets(0, 0, 5, 0);
|
||||||
|
|
||||||
//addAccounts(config.profilesData());
|
// addAccounts(config.profilesData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void redrawProfiles() throws InvalidKeySpecException, NoSuchAlgorithmException
|
private void redrawProfiles() throws InvalidKeySpecException, NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
profilesPanel.removeAll();
|
profilesPanel.removeAll();
|
||||||
c.gridy = 0;
|
c.gridy = 0;
|
||||||
@@ -433,9 +437,9 @@ class ProfilesPanel extends PluginPanel
|
|||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addAccounts(String data)
|
private void addAccounts(String data)
|
||||||
{
|
{
|
||||||
//log.info("Data: " + data);
|
// log.info("Data: " + data);
|
||||||
data = data.trim();
|
data = data.trim();
|
||||||
if (!data.contains(":"))
|
if (!data.contains(":"))
|
||||||
{
|
{
|
||||||
@@ -444,38 +448,38 @@ class ProfilesPanel extends PluginPanel
|
|||||||
Arrays.stream(data.split("\\n")).forEach(this::addAccount);
|
Arrays.stream(data.split("\\n")).forEach(this::addAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean addProfile(String data) throws InvalidKeySpecException, NoSuchAlgorithmException
|
private boolean addProfile(String data) throws InvalidKeySpecException, NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
return setProfileData(
|
return setProfileData(
|
||||||
getProfileData() + data + "\n");
|
getProfileData() + data + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeProfile(String data) throws InvalidKeySpecException, NoSuchAlgorithmException
|
void removeProfile(String data) throws InvalidKeySpecException, NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
setProfileData(
|
setProfileData(
|
||||||
getProfileData().replaceAll(data + "\\n", ""));
|
getProfileData().replaceAll(data + "\\n", ""));
|
||||||
revalidate();
|
revalidate();
|
||||||
repaint();
|
repaint();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSalt(byte[] bytes)
|
private void setSalt(byte[] bytes)
|
||||||
{
|
{
|
||||||
profilesConfig.salt(base64Encode(bytes));
|
profilesConfig.salt(base64Encode(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] getSalt()
|
private byte[] getSalt()
|
||||||
{
|
{
|
||||||
if(profilesConfig.salt().length() == 0)
|
if (profilesConfig.salt().length() == 0)
|
||||||
{
|
{
|
||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
return base64Decode(profilesConfig.salt());
|
return base64Decode(profilesConfig.salt());
|
||||||
}
|
}
|
||||||
|
|
||||||
SecretKey getAesKey() throws NoSuchAlgorithmException, InvalidKeySpecException
|
private SecretKey getAesKey() throws NoSuchAlgorithmException, InvalidKeySpecException
|
||||||
{
|
{
|
||||||
if(getSalt().length == 0)
|
if (getSalt().length == 0)
|
||||||
{
|
{
|
||||||
byte[] b = new byte[16];
|
byte[] b = new byte[16];
|
||||||
SecureRandom.getInstanceStrong().nextBytes(b);
|
SecureRandom.getInstanceStrong().nextBytes(b);
|
||||||
@@ -483,16 +487,15 @@ class ProfilesPanel extends PluginPanel
|
|||||||
}
|
}
|
||||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||||
KeySpec spec = new PBEKeySpec(txtDecryptPassword.getPassword(), getSalt(), iterations, 128);
|
KeySpec spec = new PBEKeySpec(txtDecryptPassword.getPassword(), getSalt(), iterations, 128);
|
||||||
SecretKey key = factory.generateSecret(spec);
|
return factory.generateSecret(spec);
|
||||||
return key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getProfileData() throws InvalidKeySpecException, NoSuchAlgorithmException
|
private String getProfileData() throws InvalidKeySpecException, NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
String tmp = profilesConfig.profilesData();
|
String tmp = profilesConfig.profilesData();
|
||||||
if(tmp.startsWith("¬"))
|
if (tmp.startsWith("¬"))
|
||||||
{
|
{
|
||||||
if(txtDecryptPassword.getPassword().length == 0 || String.valueOf(txtDecryptPassword.getPassword()).equals(UNLOCK_PASSWORD))
|
if (txtDecryptPassword.getPassword().length == 0 || String.valueOf(txtDecryptPassword.getPassword()).equals(UNLOCK_PASSWORD))
|
||||||
{
|
{
|
||||||
showErrorMessage("Unable to load data", "Please enter a password!");
|
showErrorMessage("Unable to load data", "Please enter a password!");
|
||||||
return tmp;
|
return tmp;
|
||||||
@@ -503,27 +506,29 @@ class ProfilesPanel extends PluginPanel
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean setProfileData(String data) throws InvalidKeySpecException, NoSuchAlgorithmException
|
private boolean setProfileData(String data) throws InvalidKeySpecException, NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
if(txtDecryptPassword.getPassword().length == 0 || String.valueOf(txtDecryptPassword.getPassword()).equals(UNLOCK_PASSWORD))
|
if (txtDecryptPassword.getPassword().length == 0 || String.valueOf(txtDecryptPassword.getPassword()).equals(UNLOCK_PASSWORD))
|
||||||
{
|
{
|
||||||
showErrorMessage("Unable to save data", "Please enter a password!");
|
showErrorMessage("Unable to save data", "Please enter a password!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
byte[] enc = encryptText(data, getAesKey());
|
byte[] enc = encryptText(data, getAesKey());
|
||||||
if(enc.length == 0)
|
if (enc.length == 0)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
String s = "¬"+base64Encode(enc);
|
}
|
||||||
|
String s = "¬" + base64Encode(enc);
|
||||||
profilesConfig.profilesData(s);
|
profilesConfig.profilesData(s);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] base64Decode(String data)
|
private byte[] base64Decode(String data)
|
||||||
{
|
{
|
||||||
return Base64.getDecoder().decode(data);
|
return Base64.getDecoder().decode(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String base64Encode(byte[] data)
|
private String base64Encode(byte[] data)
|
||||||
{
|
{
|
||||||
return Base64.getEncoder().encodeToString(data);
|
return Base64.getEncoder().encodeToString(data);
|
||||||
}
|
}
|
||||||
@@ -534,7 +539,7 @@ class ProfilesPanel extends PluginPanel
|
|||||||
* @param text text to encrypt
|
* @param text text to encrypt
|
||||||
* @return encrypted string
|
* @return encrypted string
|
||||||
*/
|
*/
|
||||||
public static byte[] encryptText(String text, SecretKey aesKey)
|
private static byte[] encryptText(String text, SecretKey aesKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -550,7 +555,7 @@ class ProfilesPanel extends PluginPanel
|
|||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String decryptText(byte[] enc, SecretKey aesKey)
|
private static String decryptText(byte[] enc, SecretKey aesKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -566,12 +571,12 @@ class ProfilesPanel extends PluginPanel
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showErrorMessage(String title, String text)
|
private static void showErrorMessage(String title, String text)
|
||||||
{
|
{
|
||||||
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(null,
|
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(null,
|
||||||
text,
|
text,
|
||||||
title,
|
title,
|
||||||
JOptionPane.ERROR_MESSAGE));
|
JOptionPane.ERROR_MESSAGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-22
@@ -25,19 +25,9 @@
|
|||||||
package net.runelite.client.plugins.profiles;
|
package net.runelite.client.plugins.profiles;
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import java.security.InvalidKeyException;
|
import java.awt.image.BufferedImage;
|
||||||
import java.security.Key;
|
import javax.inject.Inject;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.GameState;
|
|
||||||
import net.runelite.api.events.ConfigChanged;
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
@@ -46,8 +36,6 @@ import net.runelite.client.plugins.PluginType;
|
|||||||
import net.runelite.client.ui.ClientToolbar;
|
import net.runelite.client.ui.ClientToolbar;
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
import net.runelite.client.util.ImageUtil;
|
import net.runelite.client.util.ImageUtil;
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Account Switcher",
|
name = "Account Switcher",
|
||||||
@@ -60,13 +48,6 @@ public class ProfilesPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ClientToolbar clientToolbar;
|
private ClientToolbar clientToolbar;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ProfilesConfig config;
|
|
||||||
|
|
||||||
|
|
||||||
private ProfilesPanel panel;
|
private ProfilesPanel panel;
|
||||||
private NavigationButton navButton;
|
private NavigationButton navButton;
|
||||||
|
|
||||||
@@ -92,7 +73,6 @@ public class ProfilesPlugin extends Plugin
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
clientToolbar.addNavigation(navButton);
|
clientToolbar.addNavigation(navButton);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user