From 2eb074be87b85f60159fbd7155fe806ecbf80992 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Tue, 1 Jul 2014 12:41:35 -0400 Subject: [PATCH] Some fixes to the Java GUI. Thanks cuardin! [UPDATED] Allow lookup by short name. [FIXED] GUI only supports generated types, only show generated types in its list. [UPDATED] Update site password when type changes. [FIXED] Exceptions on illegal input arguments for generation, eg. empty site name. --- .../lhunath/masterpassword/MPElementType.java | 49 +++++++++++++++---- .../lhunath/masterpassword/PasswordFrame.java | 37 +++++++++----- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementType.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementType.java index 65aac140..9612e297 100644 --- a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementType.java +++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementType.java @@ -19,18 +19,21 @@ public enum MPElementType { GeneratedShort( "Short Password", "Short", "Copy-friendly, 4 characters, no symbols.", MPElementTypeClass.Generated ), GeneratedPIN( "PIN", "PIN", "4 numbers.", MPElementTypeClass.Generated ), - StoredPersonal( "Personal Password", "Personal", "AES-encrypted, exportable.", MPElementTypeClass.Stored, MPElementFeature.ExportContent ), - StoredDevicePrivate( "Device Private Password", "Private", "AES-encrypted, not exported.", MPElementTypeClass.Stored, MPElementFeature.DevicePrivate ); + StoredPersonal( "Personal Password", "Personal", "AES-encrypted, exportable.", MPElementTypeClass.Stored, + MPElementFeature.ExportContent ), + StoredDevicePrivate( "Device Private Password", "Private", "AES-encrypted, not exported.", MPElementTypeClass.Stored, + MPElementFeature.DevicePrivate ); static final Logger logger = Logger.get( MPElementType.class ); - private final MPElementTypeClass typeClass; - private final Set typeFeatures; - private final String name; - private final String shortName; + private final MPElementTypeClass typeClass; + private final Set typeFeatures; + private final String name; + private final String shortName; private final String description; - MPElementType(final String name, final String shortName, final String description, final MPElementTypeClass typeClass, final MPElementFeature... typeFeatures) { + MPElementType(final String name, final String shortName, final String description, final MPElementTypeClass typeClass, + final MPElementFeature... typeFeatures) { this.name = name; this.shortName = shortName; @@ -38,8 +41,9 @@ public enum MPElementType { this.description = description; ImmutableSet.Builder typeFeaturesBuilder = ImmutableSet.builder(); - for (final MPElementFeature typeFeature : typeFeatures) + for (final MPElementFeature typeFeature : typeFeatures) { typeFeaturesBuilder.add( typeFeature ); + } this.typeFeatures = typeFeaturesBuilder.build(); } @@ -68,12 +72,37 @@ public enum MPElementType { return description; } + /** + * @param name The full or short name of the type we want to look up. It is matched case insensitively. + * + * @return The type with the given name. + */ public static MPElementType forName(final String name) { - for (final MPElementType type : values()) - if (type.getName().equals( name )) + for (final MPElementType type : values()) { + if (type.getName().equalsIgnoreCase( name ) || type.getShortName().equalsIgnoreCase( name )) { return type; + } + } throw logger.bug( "Element type not known: %s", name ); } + + /** + * @param typeClass The class for which we look up types. + * + * @return All types that support the given class. + */ + public static ImmutableSet forClass(final MPElementTypeClass typeClass) { + + ImmutableSet.Builder types = ImmutableSet.builder(); + for (final MPElementType type : values()) { + if (type.getTypeClass() == typeClass) { + types.add( type ); + } + } + + return types.build(); + } + } diff --git a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/lhunath/masterpassword/PasswordFrame.java b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/lhunath/masterpassword/PasswordFrame.java index 83c5f183..5a898f59 100644 --- a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/lhunath/masterpassword/PasswordFrame.java +++ b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/lhunath/masterpassword/PasswordFrame.java @@ -2,14 +2,11 @@ package com.lyndir.lhunath.masterpassword; import static com.lyndir.lhunath.opal.system.util.StringUtils.*; -import com.google.common.io.Resources; +import com.google.common.collect.Iterables; import com.lyndir.lhunath.masterpassword.util.Components; import java.awt.*; import java.awt.datatransfer.StringSelection; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; @@ -38,7 +35,7 @@ public class PasswordFrame extends JFrame implements DocumentListener { { setBorder( new EmptyBorder( 20, 20, 20, 20 ) ); } - }); + } ); // User add( label = new JLabel( strf( "Generating passwords for: %s", user.getName() ) ), BorderLayout.NORTH ); @@ -83,19 +80,28 @@ public class PasswordFrame extends JFrame implements DocumentListener { } ); // Site Type & Counter + MPElementType[] types = Iterables.toArray( MPElementType.forClass( MPElementTypeClass.Generated ), MPElementType.class ); JComponent siteSettings = Components.boxLayout( BoxLayout.LINE_AXIS, // - siteTypeField = new JComboBox<>( MPElementType.values() ), - siteCounterField = new JSpinner( new SpinnerNumberModel( 1, 1, Integer.MAX_VALUE, 1 ) ) { - @Override - public Dimension getMaximumSize() { - return new Dimension( 20, getPreferredSize().height ); - } - } ); + siteTypeField = new JComboBox<>( types ), // + siteCounterField = new JSpinner( + new SpinnerNumberModel( 1, 1, Integer.MAX_VALUE, 1 ) ) { + @Override + public Dimension getMaximumSize() { + return new Dimension( 20, getPreferredSize().height ); + } + } ); siteSettings.setAlignmentX( LEFT_ALIGNMENT ); sitePanel.add( siteSettings ); siteTypeField.setAlignmentX( LEFT_ALIGNMENT ); siteTypeField.setAlignmentY( CENTER_ALIGNMENT ); siteTypeField.setSelectedItem( MPElementType.GeneratedLong ); + siteTypeField.addItemListener( new ItemListener() { + @Override + public void itemStateChanged(final ItemEvent e) { + updatePassword( null ); + } + } ); + siteCounterField.setAlignmentX( RIGHT_ALIGNMENT ); siteCounterField.setAlignmentY( CENTER_ALIGNMENT ); siteCounterField.addChangeListener( new ChangeListener() { @@ -124,6 +130,11 @@ public class PasswordFrame extends JFrame implements DocumentListener { final String siteName = siteNameField.getText(); final int siteCounter = (Integer) siteCounterField.getValue(); + if (siteType.getTypeClass() != MPElementTypeClass.Generated || siteName == null || siteName.isEmpty() || !user.hasKey()) { + passwordLabel.setText( null ); + return; + } + Res.execute( new Runnable() { @Override public void run() {