Moar UI work on the Java app + support for per-site algorithm versioning.
This commit is contained in:
parent
78c593fc08
commit
a6ab9b9194
@ -28,6 +28,7 @@ public abstract class MasterKey {
|
|||||||
return create( Version.CURRENT, fullName, masterPassword );
|
return create( Version.CURRENT, fullName, masterPassword );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public static MasterKey create(Version version, final String fullName, final String masterPassword) {
|
public static MasterKey create(Version version, final String fullName, final String masterPassword) {
|
||||||
|
|
||||||
switch (version) {
|
switch (version) {
|
||||||
@ -75,6 +76,10 @@ public abstract class MasterKey {
|
|||||||
public abstract String encode(final String siteName, final MPSiteType siteType, int siteCounter, final MPSiteVariant siteVariant,
|
public abstract String encode(final String siteName, final MPSiteType siteType, int siteCounter, final MPSiteVariant siteVariant,
|
||||||
@Nullable final String siteContext);
|
@Nullable final String siteContext);
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return masterKey != null;
|
||||||
|
}
|
||||||
|
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
|
|
||||||
if (masterKey != null) {
|
if (masterKey != null) {
|
||||||
|
@ -100,13 +100,13 @@ public class MasterKeyV0 extends MasterKey {
|
|||||||
logger.trc( "sitePasswordSeed ID: %s", CodeUtils.encodeHex( idForBytes( sitePasswordSeed ) ) );
|
logger.trc( "sitePasswordSeed ID: %s", CodeUtils.encodeHex( idForBytes( sitePasswordSeed ) ) );
|
||||||
|
|
||||||
Preconditions.checkState( sitePasswordSeed.length > 0 );
|
Preconditions.checkState( sitePasswordSeed.length > 0 );
|
||||||
int templateIndex = sitePasswordSeed[0];
|
int templateIndex = sitePasswordSeed[0] & 0xFFFF;
|
||||||
MPTemplate template = siteType.getTemplateAtRollingIndex( templateIndex );
|
MPTemplate template = siteType.getTemplateAtRollingIndex( templateIndex );
|
||||||
logger.trc( "type %s, template: %s", siteType, template.getTemplateString() );
|
logger.trc( "type %s, template: %s", siteType, template.getTemplateString() );
|
||||||
|
|
||||||
StringBuilder password = new StringBuilder( template.length() );
|
StringBuilder password = new StringBuilder( template.length() );
|
||||||
for (int i = 0; i < template.length(); ++i) {
|
for (int i = 0; i < template.length(); ++i) {
|
||||||
int characterIndex = sitePasswordSeed[i + 1];
|
int characterIndex = sitePasswordSeed[i + 1] & 0xFFFF;
|
||||||
MPTemplateCharacterClass characterClass = template.getCharacterClassAtIndex( i );
|
MPTemplateCharacterClass characterClass = template.getCharacterClassAtIndex( i );
|
||||||
char passwordCharacter = characterClass.getCharacterAtRollingIndex( characterIndex );
|
char passwordCharacter = characterClass.getCharacterAtRollingIndex( characterIndex );
|
||||||
logger.trc( "class %c, index %d (0x%02X) -> character: %c", characterClass.getIdentifier(), characterIndex,
|
logger.trc( "class %c, index %d (0x%02X) -> character: %c", characterClass.getIdentifier(), characterIndex,
|
||||||
|
@ -13,7 +13,7 @@ import javax.annotation.Nullable;
|
|||||||
*
|
*
|
||||||
* @author lhunath, 2014-08-30
|
* @author lhunath, 2014-08-30
|
||||||
*/
|
*/
|
||||||
public class MasterKeyV2 extends MasterKeyV0 {
|
public class MasterKeyV2 extends MasterKeyV1 {
|
||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
private static final Logger logger = Logger.get( MasterKeyV2.class );
|
private static final Logger logger = Logger.get( MasterKeyV2.class );
|
||||||
|
@ -14,7 +14,7 @@ import javax.annotation.Nullable;
|
|||||||
*
|
*
|
||||||
* @author lhunath, 2014-08-30
|
* @author lhunath, 2014-08-30
|
||||||
*/
|
*/
|
||||||
public class MasterKeyV3 extends MasterKeyV0 {
|
public class MasterKeyV3 extends MasterKeyV2 {
|
||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
private static final Logger logger = Logger.get( MasterKeyV3.class );
|
private static final Logger logger = Logger.get( MasterKeyV3.class );
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.lyndir.masterpassword.gui;
|
package com.lyndir.masterpassword.gui;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.lyndir.masterpassword.util.Components;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
@ -8,12 +9,13 @@ import javax.swing.*;
|
|||||||
/**
|
/**
|
||||||
* @author lhunath, 2014-06-11
|
* @author lhunath, 2014-06-11
|
||||||
*/
|
*/
|
||||||
public abstract class AuthenticationPanel extends JPanel {
|
public abstract class AuthenticationPanel extends Components.GradientPanel {
|
||||||
|
|
||||||
protected final UnlockFrame unlockFrame;
|
protected final UnlockFrame unlockFrame;
|
||||||
protected final JLabel avatarLabel;
|
protected final JLabel avatarLabel;
|
||||||
|
|
||||||
public AuthenticationPanel(final UnlockFrame unlockFrame) {
|
public AuthenticationPanel(final UnlockFrame unlockFrame) {
|
||||||
|
super( null, null );
|
||||||
this.unlockFrame = unlockFrame;
|
this.unlockFrame = unlockFrame;
|
||||||
|
|
||||||
setLayout( new BoxLayout( this, BoxLayout.PAGE_AXIS ) );
|
setLayout( new BoxLayout( this, BoxLayout.PAGE_AXIS ) );
|
||||||
|
@ -94,7 +94,7 @@ public class GUI implements UnlockFrame.SignInCallback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean signedIn(final User user) {
|
public boolean signedIn(final User user) {
|
||||||
if (!user.hasKey())
|
if (!user.isKeyAvailable())
|
||||||
return false;
|
return false;
|
||||||
try {
|
try {
|
||||||
user.getKey();
|
user.getKey();
|
||||||
|
@ -24,14 +24,10 @@ public class IncognitoAuthenticationPanel extends AuthenticationPanel implements
|
|||||||
add( Components.stud() );
|
add( Components.stud() );
|
||||||
|
|
||||||
JLabel fullNameLabel = Components.label( "Full Name:" );
|
JLabel fullNameLabel = Components.label( "Full Name:" );
|
||||||
fullNameLabel.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
fullNameLabel.setHorizontalAlignment( SwingConstants.CENTER );
|
|
||||||
fullNameLabel.setVerticalAlignment( SwingConstants.BOTTOM );
|
|
||||||
add( fullNameLabel );
|
add( fullNameLabel );
|
||||||
|
|
||||||
fullNameField = Components.textField();
|
fullNameField = Components.textField();
|
||||||
fullNameField.setFont( Res.valueFont().deriveFont( 12f ) );
|
fullNameField.setFont( Res.valueFont().deriveFont( 12f ) );
|
||||||
fullNameField.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
fullNameField.getDocument().addDocumentListener( this );
|
fullNameField.getDocument().addDocumentListener( this );
|
||||||
fullNameField.addActionListener( this );
|
fullNameField.addActionListener( this );
|
||||||
add( fullNameField );
|
add( fullNameField );
|
||||||
@ -39,13 +35,9 @@ public class IncognitoAuthenticationPanel extends AuthenticationPanel implements
|
|||||||
|
|
||||||
// Master Password
|
// Master Password
|
||||||
JLabel masterPasswordLabel = Components.label( "Master Password:" );
|
JLabel masterPasswordLabel = Components.label( "Master Password:" );
|
||||||
masterPasswordLabel.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
masterPasswordLabel.setHorizontalAlignment( SwingConstants.CENTER );
|
|
||||||
masterPasswordLabel.setVerticalAlignment( SwingConstants.BOTTOM );
|
|
||||||
add( masterPasswordLabel );
|
add( masterPasswordLabel );
|
||||||
|
|
||||||
masterPasswordField = Components.passwordField();
|
masterPasswordField = Components.passwordField();
|
||||||
masterPasswordField.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
masterPasswordField.addActionListener( this );
|
masterPasswordField.addActionListener( this );
|
||||||
masterPasswordField.getDocument().addDocumentListener( this );
|
masterPasswordField.getDocument().addDocumentListener( this );
|
||||||
add( masterPasswordField );
|
add( masterPasswordField );
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.lyndir.masterpassword.gui;
|
package com.lyndir.masterpassword.gui;
|
||||||
|
|
||||||
import com.lyndir.masterpassword.MPSiteType;
|
import com.lyndir.masterpassword.MPSiteType;
|
||||||
|
import com.lyndir.masterpassword.MasterKey;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,11 +12,14 @@ public class IncognitoSite extends Site {
|
|||||||
private String siteName;
|
private String siteName;
|
||||||
private MPSiteType siteType;
|
private MPSiteType siteType;
|
||||||
private int siteCounter;
|
private int siteCounter;
|
||||||
|
private MasterKey.Version algorithmVersion;
|
||||||
|
|
||||||
public IncognitoSite(final String siteName, final MPSiteType siteType, final int siteCounter) {
|
public IncognitoSite(final String siteName, final MPSiteType siteType, final int siteCounter,
|
||||||
|
final MasterKey.Version algorithmVersion) {
|
||||||
this.siteName = siteName;
|
this.siteName = siteName;
|
||||||
this.siteType = siteType;
|
this.siteType = siteType;
|
||||||
this.siteCounter = siteCounter;
|
this.siteCounter = siteCounter;
|
||||||
|
this.algorithmVersion = algorithmVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSiteName() {
|
public String getSiteName() {
|
||||||
@ -34,6 +38,16 @@ public class IncognitoSite extends Site {
|
|||||||
this.siteType = siteType;
|
this.siteType = siteType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MasterKey.Version getAlgorithmVersion() {
|
||||||
|
return algorithmVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlgorithmVersion(final MasterKey.Version algorithmVersion) {
|
||||||
|
this.algorithmVersion = algorithmVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public int getSiteCounter() {
|
public int getSiteCounter() {
|
||||||
return siteCounter;
|
return siteCounter;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ public class IncognitoUser extends User {
|
|||||||
|
|
||||||
private final String fullName;
|
private final String fullName;
|
||||||
private final String masterPassword;
|
private final String masterPassword;
|
||||||
|
private MasterKey.Version algorithmVersion;
|
||||||
|
|
||||||
public IncognitoUser(final String fullName, final String masterPassword) {
|
public IncognitoUser(final String fullName, final String masterPassword) {
|
||||||
this.fullName = fullName;
|
this.fullName = fullName;
|
||||||
@ -28,7 +29,12 @@ public class IncognitoUser extends User {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MasterKey.Version getAlgorithmVersion() {
|
public MasterKey.Version getAlgorithmVersion() {
|
||||||
return MasterKey.Version.CURRENT;
|
return algorithmVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlgorithmVersion(final MasterKey.Version algorithmVersion) {
|
||||||
|
this.algorithmVersion = algorithmVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,19 +44,10 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
|
|||||||
|
|
||||||
// User
|
// User
|
||||||
JLabel userLabel = Components.label( "User:" );
|
JLabel userLabel = Components.label( "User:" );
|
||||||
userLabel.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
userLabel.setHorizontalAlignment( SwingConstants.CENTER );
|
|
||||||
userLabel.setVerticalAlignment( SwingConstants.BOTTOM );
|
|
||||||
add( userLabel );
|
add( userLabel );
|
||||||
|
|
||||||
userField = new JComboBox<ModelUser>( new DefaultComboBoxModel<>( readConfigUsers() ) ) {
|
userField = Components.comboBox( readConfigUsers() );
|
||||||
@Override
|
|
||||||
public Dimension getMaximumSize() {
|
|
||||||
return new Dimension( Integer.MAX_VALUE, getPreferredSize().height );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
userField.setFont( Res.valueFont().deriveFont( 12f ) );
|
userField.setFont( Res.valueFont().deriveFont( 12f ) );
|
||||||
userField.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
userField.addItemListener( this );
|
userField.addItemListener( this );
|
||||||
userField.addActionListener( this );
|
userField.addActionListener( this );
|
||||||
add( userField );
|
add( userField );
|
||||||
@ -64,13 +55,9 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
|
|||||||
|
|
||||||
// Master Password
|
// Master Password
|
||||||
masterPasswordLabel = Components.label( "Master Password:" );
|
masterPasswordLabel = Components.label( "Master Password:" );
|
||||||
masterPasswordLabel.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
masterPasswordLabel.setHorizontalAlignment( SwingConstants.CENTER );
|
|
||||||
masterPasswordLabel.setVerticalAlignment( SwingConstants.BOTTOM );
|
|
||||||
add( masterPasswordLabel );
|
add( masterPasswordLabel );
|
||||||
|
|
||||||
masterPasswordField = Components.passwordField();
|
masterPasswordField = Components.passwordField();
|
||||||
masterPasswordField.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
masterPasswordField.addActionListener( this );
|
masterPasswordField.addActionListener( this );
|
||||||
masterPasswordField.getDocument().addDocumentListener( this );
|
masterPasswordField.getDocument().addDocumentListener( this );
|
||||||
add( masterPasswordField );
|
add( masterPasswordField );
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.lyndir.masterpassword.gui;
|
package com.lyndir.masterpassword.gui;
|
||||||
|
|
||||||
import com.lyndir.masterpassword.MPSiteType;
|
import com.lyndir.masterpassword.MPSiteType;
|
||||||
|
import com.lyndir.masterpassword.MasterKey;
|
||||||
import com.lyndir.masterpassword.model.*;
|
import com.lyndir.masterpassword.model.*;
|
||||||
|
|
||||||
|
|
||||||
@ -37,6 +38,19 @@ public class ModelSite extends Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MasterKey.Version getAlgorithmVersion() {
|
||||||
|
return model.getAlgorithmVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlgorithmVersion(final MasterKey.Version algorithmVersion) {
|
||||||
|
if (algorithmVersion != getAlgorithmVersion()) {
|
||||||
|
model.setAlgorithmVersion( algorithmVersion );
|
||||||
|
MPUserFileManager.get().save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int getSiteCounter() {
|
public int getSiteCounter() {
|
||||||
return model.getSiteCounter();
|
return model.getSiteCounter();
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,12 @@ public class ModelUser extends User {
|
|||||||
return model.getAlgorithmVersion();
|
return model.getAlgorithmVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlgorithmVersion(final MasterKey.Version algorithmVersion) {
|
||||||
|
model.setAlgorithmVersion( algorithmVersion );
|
||||||
|
MPUserFileManager.get().save();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAvatar() {
|
public int getAvatar() {
|
||||||
return model.getAvatar();
|
return model.getAvatar();
|
||||||
|
@ -21,9 +21,11 @@ import javax.swing.event.*;
|
|||||||
public class PasswordFrame extends JFrame implements DocumentListener {
|
public class PasswordFrame extends JFrame implements DocumentListener {
|
||||||
|
|
||||||
private final User user;
|
private final User user;
|
||||||
|
private final Components.GradientPanel root;
|
||||||
private final JTextField siteNameField;
|
private final JTextField siteNameField;
|
||||||
private final JButton siteAddButton;
|
private final JButton siteAddButton;
|
||||||
private final JComboBox<MPSiteType> siteTypeField;
|
private final JComboBox<MPSiteType> siteTypeField;
|
||||||
|
private final JComboBox<MasterKey.Version> siteVersionField;
|
||||||
private final JSpinner siteCounterField;
|
private final JSpinner siteCounterField;
|
||||||
private final JPasswordField passwordField;
|
private final JPasswordField passwordField;
|
||||||
private final JLabel tipLabel;
|
private final JLabel tipLabel;
|
||||||
@ -38,34 +40,26 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
super( "Master Password" );
|
super( "Master Password" );
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
|
||||||
JLabel label;
|
|
||||||
|
|
||||||
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
|
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
|
||||||
setContentPane( new JPanel( new BorderLayout( 20, 20 ) ) {
|
setContentPane( root = Components.gradientPanel( new BorderLayout( 20, 20 ), Res.colors().frameBg() ) );
|
||||||
{
|
root.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
|
||||||
setBackground( Res.colors().frameBg() );
|
|
||||||
setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
// User
|
|
||||||
add( label = Components.label( strf( "Generating passwords for: %s", user.getFullName() ) ), BorderLayout.NORTH );
|
|
||||||
label.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
|
|
||||||
// Site
|
// Site
|
||||||
JPanel sitePanel = Components.boxLayout( BoxLayout.PAGE_AXIS );
|
JPanel sitePanel = Components.boxLayout( BoxLayout.PAGE_AXIS );
|
||||||
|
sitePanel.setOpaque( true );
|
||||||
sitePanel.setBackground( Res.colors().controlBg() );
|
sitePanel.setBackground( Res.colors().controlBg() );
|
||||||
sitePanel.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
|
sitePanel.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
|
||||||
add( Components.bordered( sitePanel, BorderFactory.createRaisedBevelBorder(), Res.colors().frameBg() ), BorderLayout.CENTER );
|
add( Components.bordered( sitePanel, BorderFactory.createRaisedBevelBorder(), Res.colors().frameBg() ), BorderLayout.CENTER );
|
||||||
|
|
||||||
// Site Name
|
// User
|
||||||
sitePanel.add( label = Components.label( "Site Name:" ) );
|
sitePanel.add( Components.label( strf( "Generating passwords for: %s", user.getFullName() ), JLabel.CENTER ) );
|
||||||
label.setAlignmentX( LEFT_ALIGNMENT );
|
sitePanel.add( Components.stud() );
|
||||||
|
|
||||||
|
// Site Name
|
||||||
|
sitePanel.add( Components.label( "Site Name:" ) );
|
||||||
JComponent siteControls = Components.boxLayout( BoxLayout.LINE_AXIS, //
|
JComponent siteControls = Components.boxLayout( BoxLayout.LINE_AXIS, //
|
||||||
siteNameField = Components.textField(), Components.stud(),
|
siteNameField = Components.textField(), Components.stud(),
|
||||||
siteAddButton = Components.button( "Add Site" ) );
|
siteAddButton = Components.button( "Add Site" ) );
|
||||||
siteNameField.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
siteNameField.getDocument().addDocumentListener( this );
|
siteNameField.getDocument().addDocumentListener( this );
|
||||||
siteNameField.addActionListener( new ActionListener() {
|
siteNameField.addActionListener( new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -94,8 +88,6 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
siteAddButton.setVisible( false );
|
siteAddButton.setVisible( false );
|
||||||
siteAddButton.setAlignmentX( RIGHT_ALIGNMENT );
|
|
||||||
siteAddButton.setAlignmentY( CENTER_ALIGNMENT );
|
|
||||||
siteAddButton.addActionListener( new ActionListener() {
|
siteAddButton.addActionListener( new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(final ActionEvent e) {
|
public void actionPerformed(final ActionEvent e) {
|
||||||
@ -103,23 +95,20 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
siteAddButton.setVisible( false );
|
siteAddButton.setVisible( false );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
siteControls.setBackground( null );
|
|
||||||
siteControls.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
sitePanel.add( siteControls );
|
sitePanel.add( siteControls );
|
||||||
|
sitePanel.add( Components.stud() );
|
||||||
|
|
||||||
// Site Type & Counter
|
// Site Type & Counter
|
||||||
MPSiteType[] types = Iterables.toArray( MPSiteType.forClass( MPSiteTypeClass.Generated ), MPSiteType.class );
|
MPSiteType[] types = Iterables.toArray( MPSiteType.forClass( MPSiteTypeClass.Generated ), MPSiteType.class );
|
||||||
JComponent siteSettings = Components.boxLayout( BoxLayout.LINE_AXIS, //
|
JComponent siteSettings = Components.boxLayout( BoxLayout.LINE_AXIS, //
|
||||||
siteTypeField = new JComboBox<>( types ), //
|
siteTypeField = Components.comboBox( types ), //
|
||||||
|
Components.stud(), //
|
||||||
|
siteVersionField = Components.comboBox( MasterKey.Version.values() ), //
|
||||||
Components.stud(), //
|
Components.stud(), //
|
||||||
siteCounterField = Components.spinner(
|
siteCounterField = Components.spinner(
|
||||||
new SpinnerNumberModel( 1, 1, Integer.MAX_VALUE, 1 ) ) );
|
new SpinnerNumberModel( 1, 1, Integer.MAX_VALUE, 1 ) ) );
|
||||||
siteSettings.setBackground( null );
|
|
||||||
siteSettings.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
sitePanel.add( siteSettings );
|
sitePanel.add( siteSettings );
|
||||||
siteTypeField.setFont( Res.valueFont().deriveFont( 12f ) );
|
siteTypeField.setFont( Res.valueFont().deriveFont( 12f ) );
|
||||||
siteTypeField.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
siteTypeField.setAlignmentY( CENTER_ALIGNMENT );
|
|
||||||
siteTypeField.setSelectedItem( MPSiteType.GeneratedLong );
|
siteTypeField.setSelectedItem( MPSiteType.GeneratedLong );
|
||||||
siteTypeField.addItemListener( new ItemListener() {
|
siteTypeField.addItemListener( new ItemListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -128,9 +117,18 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
siteVersionField.setFont( Res.valueFont().deriveFont( 12f ) );
|
||||||
|
siteVersionField.setAlignmentX( RIGHT_ALIGNMENT );
|
||||||
|
siteVersionField.setSelectedItem( user.getAlgorithmVersion() );
|
||||||
|
siteVersionField.addItemListener( new ItemListener() {
|
||||||
|
@Override
|
||||||
|
public void itemStateChanged(final ItemEvent e) {
|
||||||
|
updatePassword();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
siteCounterField.setFont( Res.valueFont().deriveFont( 12f ) );
|
siteCounterField.setFont( Res.valueFont().deriveFont( 12f ) );
|
||||||
siteCounterField.setAlignmentX( RIGHT_ALIGNMENT );
|
siteCounterField.setAlignmentX( RIGHT_ALIGNMENT );
|
||||||
siteCounterField.setAlignmentY( CENTER_ALIGNMENT );
|
|
||||||
siteCounterField.addChangeListener( new ChangeListener() {
|
siteCounterField.addChangeListener( new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(final ChangeEvent e) {
|
public void stateChanged(final ChangeEvent e) {
|
||||||
@ -151,9 +149,11 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
|
|
||||||
// Password
|
// Password
|
||||||
passwordField = new JPasswordField();
|
passwordField = new JPasswordField();
|
||||||
|
passwordField.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||||
passwordField.setEditable( false );
|
passwordField.setEditable( false );
|
||||||
passwordField.setHorizontalAlignment( JTextField.CENTER );
|
passwordField.setHorizontalAlignment( JTextField.CENTER );
|
||||||
passwordField.putClientProperty( "JPasswordField.cutCopyAllowed", true );
|
passwordField.putClientProperty( "JPasswordField.cutCopyAllowed", true );
|
||||||
|
passwordField.setBorder( null );
|
||||||
passwordEchoChar = passwordField.getEchoChar();
|
passwordEchoChar = passwordField.getEchoChar();
|
||||||
passwordEchoFont = passwordField.getFont().deriveFont( 40f );
|
passwordEchoFont = passwordField.getFont().deriveFont( 40f );
|
||||||
updateMask();
|
updateMask();
|
||||||
@ -161,16 +161,15 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
// Tip
|
// Tip
|
||||||
tipLabel = Components.label( " ", JLabel.CENTER );
|
tipLabel = Components.label( " ", JLabel.CENTER );
|
||||||
tipLabel.setAlignmentX( Component.CENTER_ALIGNMENT );
|
tipLabel.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||||
|
JPanel passwordContainer = Components.boxLayout( BoxLayout.PAGE_AXIS, maskPasswordField, passwordField, tipLabel );
|
||||||
JPanel passwordContainer = Components.boxLayout( BoxLayout.PAGE_AXIS, maskPasswordField,
|
passwordContainer.setOpaque( true );
|
||||||
Components.bordered( passwordField, BorderFactory.createLoweredSoftBevelBorder(),
|
passwordContainer.setBackground( Color.white );
|
||||||
Res.colors().frameBg() ), tipLabel );
|
passwordContainer.setBorder( BorderFactory.createEmptyBorder( 8, 8, 8, 8 ) );
|
||||||
passwordContainer.setBackground( null );
|
add( Components.bordered( passwordContainer, BorderFactory.createLoweredSoftBevelBorder(), Res.colors().frameBg() ),
|
||||||
add( passwordContainer, BorderLayout.SOUTH );
|
BorderLayout.SOUTH );
|
||||||
|
|
||||||
pack();
|
pack();
|
||||||
setMinimumSize( getSize() );
|
setMinimumSize( new Dimension( Math.max( 600, getPreferredSize().width ), Math.max( 300, getPreferredSize().height ) ) );
|
||||||
setPreferredSize( new Dimension( 600, getSize().height ) );
|
|
||||||
pack();
|
pack();
|
||||||
|
|
||||||
setLocationByPlatform( true );
|
setLocationByPlatform( true );
|
||||||
@ -188,19 +187,21 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
final String siteNameQuery = siteNameField.getText();
|
final String siteNameQuery = siteNameField.getText();
|
||||||
if (updatingUI)
|
if (updatingUI)
|
||||||
return Futures.immediateCancelledFuture();
|
return Futures.immediateCancelledFuture();
|
||||||
if (siteNameQuery == null || siteNameQuery.isEmpty() || !user.hasKey()) {
|
if (siteNameQuery == null || siteNameQuery.isEmpty() || !user.isKeyAvailable()) {
|
||||||
tipLabel.setText( null );
|
tipLabel.setText( null );
|
||||||
passwordField.setText( null );
|
passwordField.setText( null );
|
||||||
return Futures.immediateCancelledFuture();
|
return Futures.immediateCancelledFuture();
|
||||||
}
|
}
|
||||||
|
|
||||||
MPSiteType siteType = siteTypeField.getModel().getElementAt( siteTypeField.getSelectedIndex() );
|
final MPSiteType siteType = siteTypeField.getModel().getElementAt( siteTypeField.getSelectedIndex() );
|
||||||
|
final MasterKey.Version siteVersion = siteVersionField.getItemAt( siteVersionField.getSelectedIndex() );
|
||||||
final int siteCounter = (Integer) siteCounterField.getValue();
|
final int siteCounter = (Integer) siteCounterField.getValue();
|
||||||
final Site site = currentSite != null && currentSite.getSiteName().equals( siteNameQuery )? currentSite
|
final Site site = currentSite != null && currentSite.getSiteName().equals( siteNameQuery )? currentSite
|
||||||
: Iterables.getFirst( user.findSitesByName( siteNameQuery ), new IncognitoSite( siteNameQuery, siteType, siteCounter ) );
|
: Iterables.getFirst( user.findSitesByName( siteNameQuery ), new IncognitoSite( siteNameQuery, siteType, siteCounter, user.getAlgorithmVersion() ) );
|
||||||
assert site != null;
|
assert site != null;
|
||||||
if (site == currentSite) {
|
if (site == currentSite) {
|
||||||
site.setSiteType( siteType );
|
site.setSiteType( siteType );
|
||||||
|
site.setAlgorithmVersion( siteVersion );
|
||||||
site.setSiteCounter( siteCounter );
|
site.setSiteCounter( siteCounter );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +209,8 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
@Override
|
@Override
|
||||||
public String call()
|
public String call()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return user.getKey().encode( site.getSiteName(), site.getSiteType(), site.getSiteCounter(), MPSiteVariant.Password, null );
|
return user.getKey( site.getAlgorithmVersion() )
|
||||||
|
.encode( site.getSiteName(), site.getSiteType(), site.getSiteCounter(), MPSiteVariant.Password, null );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
Futures.addCallback( passwordFuture, new FutureCallback<String>() {
|
Futures.addCallback( passwordFuture, new FutureCallback<String>() {
|
||||||
@ -221,6 +223,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
currentSite = site;
|
currentSite = site;
|
||||||
siteAddButton.setVisible( user instanceof ModelUser && !(currentSite instanceof ModelSite) );
|
siteAddButton.setVisible( user instanceof ModelUser && !(currentSite instanceof ModelSite) );
|
||||||
siteTypeField.setSelectedItem( currentSite.getSiteType() );
|
siteTypeField.setSelectedItem( currentSite.getSiteType() );
|
||||||
|
siteVersionField.setSelectedItem( currentSite.getAlgorithmVersion() );
|
||||||
siteCounterField.setValue( currentSite.getSiteCounter() );
|
siteCounterField.setValue( currentSite.getSiteCounter() );
|
||||||
siteNameField.setText( currentSite.getSiteName() );
|
siteNameField.setText( currentSite.getSiteName() );
|
||||||
if (siteNameField.getText().startsWith( siteNameQuery ))
|
if (siteNameField.getText().startsWith( siteNameQuery ))
|
||||||
|
@ -3,6 +3,7 @@ package com.lyndir.masterpassword.gui;
|
|||||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||||
|
|
||||||
import com.lyndir.masterpassword.MPSiteType;
|
import com.lyndir.masterpassword.MPSiteType;
|
||||||
|
import com.lyndir.masterpassword.MasterKey;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,6 +19,10 @@ public abstract class Site {
|
|||||||
|
|
||||||
public abstract void setSiteType(final MPSiteType siteType);
|
public abstract void setSiteType(final MPSiteType siteType);
|
||||||
|
|
||||||
|
public abstract MasterKey.Version getAlgorithmVersion();
|
||||||
|
|
||||||
|
public abstract void setAlgorithmVersion(final MasterKey.Version algorithmVersion);
|
||||||
|
|
||||||
public abstract int getSiteCounter();
|
public abstract int getSiteCounter();
|
||||||
|
|
||||||
public abstract void setSiteCounter(final int siteCounter);
|
public abstract void setSiteCounter(final int siteCounter);
|
||||||
|
@ -6,7 +6,6 @@ import com.lyndir.masterpassword.util.Components;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.*;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +14,7 @@ import javax.swing.border.*;
|
|||||||
public class UnlockFrame extends JFrame {
|
public class UnlockFrame extends JFrame {
|
||||||
|
|
||||||
private final SignInCallback signInCallback;
|
private final SignInCallback signInCallback;
|
||||||
private final JPanel root;
|
private final Components.GradientPanel root;
|
||||||
private final JButton signInButton;
|
private final JButton signInButton;
|
||||||
private final JPanel authenticationContainer;
|
private final JPanel authenticationContainer;
|
||||||
private AuthenticationPanel authenticationPanel;
|
private AuthenticationPanel authenticationPanel;
|
||||||
@ -28,11 +27,11 @@ public class UnlockFrame extends JFrame {
|
|||||||
this.signInCallback = signInCallback;
|
this.signInCallback = signInCallback;
|
||||||
|
|
||||||
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
|
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
|
||||||
setContentPane( root = new JPanel( new BorderLayout( 20, 20 ) ) );
|
setContentPane( root = Components.gradientPanel( new BorderLayout( 20, 20 ), Res.colors().frameBg() ) );
|
||||||
root.setBackground( Res.colors().frameBg() );
|
root.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
|
||||||
root.setBorder( new EmptyBorder( 20, 20, 20, 20 ) );
|
|
||||||
|
|
||||||
authenticationContainer = Components.boxLayout( BoxLayout.PAGE_AXIS );
|
authenticationContainer = Components.boxLayout( BoxLayout.PAGE_AXIS );
|
||||||
|
authenticationContainer.setOpaque( true );
|
||||||
authenticationContainer.setBackground( Res.colors().controlBg() );
|
authenticationContainer.setBackground( Res.colors().controlBg() );
|
||||||
authenticationContainer.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
|
authenticationContainer.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
|
||||||
add( Components.bordered( authenticationContainer, BorderFactory.createRaisedBevelBorder(), Res.colors().frameBg() ) );
|
add( Components.bordered( authenticationContainer, BorderFactory.createRaisedBevelBorder(), Res.colors().frameBg() ) );
|
||||||
@ -42,7 +41,6 @@ public class UnlockFrame extends JFrame {
|
|||||||
Box.createGlue() );
|
Box.createGlue() );
|
||||||
signInBox.setBackground( null );
|
signInBox.setBackground( null );
|
||||||
root.add( signInBox, BorderLayout.SOUTH );
|
root.add( signInBox, BorderLayout.SOUTH );
|
||||||
signInButton.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
signInButton.addActionListener( new AbstractAction() {
|
signInButton.addActionListener( new AbstractAction() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(final ActionEvent e) {
|
public void actionPerformed(final ActionEvent e) {
|
||||||
@ -75,7 +73,6 @@ public class UnlockFrame extends JFrame {
|
|||||||
authenticationContainer.add( Components.stud() );
|
authenticationContainer.add( Components.stud() );
|
||||||
|
|
||||||
final JCheckBox incognitoCheckBox = Components.checkBox( "Incognito" );
|
final JCheckBox incognitoCheckBox = Components.checkBox( "Incognito" );
|
||||||
incognitoCheckBox.setAlignmentX( LEFT_ALIGNMENT );
|
|
||||||
incognitoCheckBox.setSelected( incognito );
|
incognitoCheckBox.setSelected( incognito );
|
||||||
incognitoCheckBox.addItemListener( new ItemListener() {
|
incognitoCheckBox.addItemListener( new ItemListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -91,7 +88,6 @@ public class UnlockFrame extends JFrame {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
JComponent toolsPanel = Components.boxLayout( BoxLayout.LINE_AXIS, incognitoCheckBox, Box.createGlue() );
|
JComponent toolsPanel = Components.boxLayout( BoxLayout.LINE_AXIS, incognitoCheckBox, Box.createGlue() );
|
||||||
toolsPanel.setAlignmentX( Component.LEFT_ALIGNMENT );
|
|
||||||
authenticationContainer.add( toolsPanel );
|
authenticationContainer.add( toolsPanel );
|
||||||
for (JButton button : authenticationPanel.getButtons()) {
|
for (JButton button : authenticationPanel.getButtons()) {
|
||||||
button.setMargin( new Insets( 0, 0, 0, 0 ) );
|
button.setMargin( new Insets( 0, 0, 0, 0 ) );
|
||||||
@ -118,7 +114,7 @@ public class UnlockFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean checkSignIn() {
|
boolean checkSignIn() {
|
||||||
boolean enabled = user != null && !user.getFullName().isEmpty() && user.hasKey();
|
boolean enabled = user != null && !user.getFullName().isEmpty() && user.isKeyAvailable();
|
||||||
signInButton.setEnabled( enabled );
|
signInButton.setEnabled( enabled );
|
||||||
|
|
||||||
return enabled;
|
return enabled;
|
||||||
|
@ -2,9 +2,9 @@ package com.lyndir.masterpassword.gui;
|
|||||||
|
|
||||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.lyndir.masterpassword.MasterKey;
|
import com.lyndir.masterpassword.MasterKey;
|
||||||
import com.lyndir.masterpassword.model.MPUser;
|
import java.util.EnumMap;
|
||||||
import java.security.KeyException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@ -14,7 +14,8 @@ import javax.annotation.Nonnull;
|
|||||||
*/
|
*/
|
||||||
public abstract class User {
|
public abstract class User {
|
||||||
|
|
||||||
private MasterKey key;
|
@Nonnull
|
||||||
|
private static final EnumMap<MasterKey.Version, MasterKey> keyByVersion = Maps.newEnumMap( MasterKey.Version.class );
|
||||||
|
|
||||||
public abstract String getFullName();
|
public abstract String getFullName();
|
||||||
|
|
||||||
@ -22,32 +23,42 @@ public abstract class User {
|
|||||||
|
|
||||||
public abstract MasterKey.Version getAlgorithmVersion();
|
public abstract MasterKey.Version getAlgorithmVersion();
|
||||||
|
|
||||||
|
public abstract void setAlgorithmVersion(final MasterKey.Version algorithmVersion);
|
||||||
|
|
||||||
public int getAvatar() {
|
public int getAvatar() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasKey() {
|
public boolean isKeyAvailable() {
|
||||||
String masterPassword = getMasterPassword();
|
String masterPassword = getMasterPassword();
|
||||||
return key != null || (masterPassword != null && !masterPassword.isEmpty());
|
return masterPassword != null && !masterPassword.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public MasterKey getKey() throws MasterKeyException {
|
public MasterKey getKey() throws MasterKeyException {
|
||||||
if (key == null) {
|
return getKey( getAlgorithmVersion() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public MasterKey getKey(MasterKey.Version algorithmVersion) throws MasterKeyException {
|
||||||
String masterPassword = getMasterPassword();
|
String masterPassword = getMasterPassword();
|
||||||
if (masterPassword == null || masterPassword.isEmpty()) {
|
if (masterPassword == null || masterPassword.isEmpty()) {
|
||||||
reset();
|
reset();
|
||||||
throw new MasterKeyException( strf( "Master password unknown for user: %s", getFullName() ) );
|
throw new MasterKeyException( strf( "Master password unknown for user: %s", getFullName() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
key = MasterKey.create( getAlgorithmVersion(), getFullName(), masterPassword );
|
MasterKey key = keyByVersion.get( algorithmVersion );
|
||||||
}
|
if (key == null)
|
||||||
|
keyByVersion.put( algorithmVersion, key = MasterKey.create( algorithmVersion, getFullName(), masterPassword ) );
|
||||||
|
if (!key.isValid())
|
||||||
|
key.revalidate( masterPassword );
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
key = null;
|
for (MasterKey key : keyByVersion.values())
|
||||||
|
key.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Iterable<Site> findSitesByName(final String siteName);
|
public abstract Iterable<Site> findSitesByName(final String siteName);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.lyndir.masterpassword.util;
|
package com.lyndir.masterpassword.util;
|
||||||
|
|
||||||
|
import com.lyndir.masterpassword.gui.ModelUser;
|
||||||
import com.lyndir.masterpassword.gui.Res;
|
import com.lyndir.masterpassword.gui.Res;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@ -12,8 +13,9 @@ import javax.swing.border.CompoundBorder;
|
|||||||
*/
|
*/
|
||||||
public abstract class Components {
|
public abstract class Components {
|
||||||
|
|
||||||
public static JPanel boxLayout(int axis, Component... components) {
|
public static GradientPanel boxLayout(int axis, Component... components) {
|
||||||
JPanel container = new JPanel();
|
GradientPanel container = gradientPanel( null, null );
|
||||||
|
// container.setBackground( Color.red );
|
||||||
container.setLayout( new BoxLayout( container, axis ) );
|
container.setLayout( new BoxLayout( container, axis ) );
|
||||||
for (Component component : components)
|
for (Component component : components)
|
||||||
container.add( component );
|
container.add( component );
|
||||||
@ -21,12 +23,12 @@ public abstract class Components {
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JPanel bordered(final JComponent component, final Border border) {
|
public static GradientPanel bordered(final JComponent component, final Border border) {
|
||||||
return bordered( component, border, null );
|
return bordered( component, border, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JPanel bordered(final JComponent component, final Border border, Color background) {
|
public static GradientPanel bordered(final JComponent component, final Border border, Color background) {
|
||||||
JPanel box = boxLayout( BoxLayout.LINE_AXIS, component );
|
GradientPanel box = boxLayout( BoxLayout.LINE_AXIS, component );
|
||||||
|
|
||||||
if (border != null)
|
if (border != null)
|
||||||
box.setBorder( border );
|
box.setBorder( border );
|
||||||
@ -37,12 +39,25 @@ public abstract class Components {
|
|||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GradientPanel gradientPanel(final LayoutManager layout, final Color color) {
|
||||||
|
return new GradientPanel( layout, color ) {
|
||||||
|
{
|
||||||
|
setOpaque( color != null );
|
||||||
|
setBackground( null );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static JTextField textField() {
|
public static JTextField textField() {
|
||||||
return new JTextField() {
|
return new JTextField() {
|
||||||
{
|
{
|
||||||
setBorder( BorderFactory.createCompoundBorder( BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ),
|
setBorder( BorderFactory.createCompoundBorder( BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ),
|
||||||
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) ) );
|
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) ) );
|
||||||
setFont( Res.valueFont().deriveFont( 12f ) );
|
setFont( Res.valueFont().deriveFont( 12f ) );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +72,8 @@ public abstract class Components {
|
|||||||
{
|
{
|
||||||
setBorder( BorderFactory.createCompoundBorder( BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ),
|
setBorder( BorderFactory.createCompoundBorder( BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ),
|
||||||
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) ) );
|
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) ) );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -70,6 +87,8 @@ public abstract class Components {
|
|||||||
return new JButton( label ) {
|
return new JButton( label ) {
|
||||||
{
|
{
|
||||||
setFont( Res.controlFont().deriveFont( 12f ) );
|
setFont( Res.controlFont().deriveFont( 12f ) );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -80,7 +99,12 @@ public abstract class Components {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Component stud() {
|
public static Component stud() {
|
||||||
return Box.createRigidArea( new Dimension( 8, 8 ) );
|
Dimension studDimension = new Dimension( 8, 8 );
|
||||||
|
Box.Filler rigidArea = new Box.Filler( studDimension, studDimension, studDimension );
|
||||||
|
rigidArea.setAlignmentX( Component.LEFT_ALIGNMENT );
|
||||||
|
rigidArea.setAlignmentY( Component.BOTTOM_ALIGNMENT );
|
||||||
|
rigidArea.setBackground( Color.red );
|
||||||
|
return rigidArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSpinner spinner(final SpinnerModel model) {
|
public static JSpinner spinner(final SpinnerModel model) {
|
||||||
@ -90,6 +114,8 @@ public abstract class Components {
|
|||||||
BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ),
|
BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ),
|
||||||
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) );
|
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) );
|
||||||
((DefaultEditor) getEditor()).getTextField().setBorder( editorBorder );
|
((DefaultEditor) getEditor()).getTextField().setBorder( editorBorder );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -107,6 +133,13 @@ public abstract class Components {
|
|||||||
return new JLabel( label, alignment ) {
|
return new JLabel( label, alignment ) {
|
||||||
{
|
{
|
||||||
setFont( Res.controlFont().deriveFont( 12f ) );
|
setFont( Res.controlFont().deriveFont( 12f ) );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getMaximumSize() {
|
||||||
|
return new Dimension( Integer.MAX_VALUE, getPreferredSize().height );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -115,7 +148,67 @@ public abstract class Components {
|
|||||||
return new JCheckBox( label ) {
|
return new JCheckBox( label ) {
|
||||||
{
|
{
|
||||||
setFont( Res.controlFont().deriveFont( 12f ) );
|
setFont( Res.controlFont().deriveFont( 12f ) );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static <V> JComboBox<V> comboBox(final V... values) {
|
||||||
|
return comboBox( new DefaultComboBoxModel<>( values ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <M> JComboBox<M> comboBox(final ComboBoxModel<M> model) {
|
||||||
|
return new JComboBox<M>( model ) {
|
||||||
|
{
|
||||||
|
setFont( Res.controlFont().deriveFont( 12f ) );
|
||||||
|
setAlignmentX( LEFT_ALIGNMENT );
|
||||||
|
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getMaximumSize() {
|
||||||
|
return new Dimension( Integer.MAX_VALUE, getPreferredSize().height );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GradientPanel extends JPanel {
|
||||||
|
|
||||||
|
private Color gradientColor;
|
||||||
|
private GradientPaint paint;
|
||||||
|
|
||||||
|
protected GradientPanel(final LayoutManager layout, final Color gradientColor) {
|
||||||
|
super( layout );
|
||||||
|
this.gradientColor = gradientColor;
|
||||||
|
setBackground( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getGradientColor() {
|
||||||
|
return gradientColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGradientColor(final Color gradientColor) {
|
||||||
|
this.gradientColor = gradientColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doLayout() {
|
||||||
|
super.doLayout();
|
||||||
|
|
||||||
|
if (gradientColor != null)
|
||||||
|
paint = new GradientPaint( new Point( 0, 0 ), gradientColor, new Point( getWidth(), getHeight() ), gradientColor.darker() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(final Graphics g) {
|
||||||
|
super.paintComponent( g );
|
||||||
|
|
||||||
|
if (paint != null) {
|
||||||
|
((Graphics2D) g).setPaint( paint );
|
||||||
|
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
|||||||
import com.lyndir.masterpassword.*;
|
import com.lyndir.masterpassword.*;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.Instant;
|
import org.joda.time.Instant;
|
||||||
|
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ public class MPSite {
|
|||||||
public static final int DEFAULT_COUNTER = 1;
|
public static final int DEFAULT_COUNTER = 1;
|
||||||
|
|
||||||
private final MPUser user;
|
private final MPUser user;
|
||||||
private MasterKey.Version mpVersion;
|
private MasterKey.Version algorithmVersion;
|
||||||
private Instant lastUsed;
|
private Instant lastUsed;
|
||||||
private String siteName;
|
private String siteName;
|
||||||
private MPSiteType siteType;
|
private MPSiteType siteType;
|
||||||
@ -33,17 +32,17 @@ public class MPSite {
|
|||||||
|
|
||||||
public MPSite(final MPUser user, final String siteName, final MPSiteType siteType, final int siteCounter) {
|
public MPSite(final MPUser user, final String siteName, final MPSiteType siteType, final int siteCounter) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.mpVersion = MasterKey.Version.CURRENT;
|
this.algorithmVersion = MasterKey.Version.CURRENT;
|
||||||
this.lastUsed = new Instant();
|
this.lastUsed = new Instant();
|
||||||
this.siteName = siteName;
|
this.siteName = siteName;
|
||||||
this.siteType = siteType;
|
this.siteType = siteType;
|
||||||
this.siteCounter = siteCounter;
|
this.siteCounter = siteCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MPSite(final MPUser user, final MasterKey.Version mpVersion, final Instant lastUsed, final String siteName, final MPSiteType siteType, final int siteCounter,
|
protected MPSite(final MPUser user, final MasterKey.Version algorithmVersion, final Instant lastUsed, final String siteName, final MPSiteType siteType, final int siteCounter,
|
||||||
final int uses, final String loginName, final String importContent) {
|
final int uses, final String loginName, final String importContent) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.mpVersion = mpVersion;
|
this.algorithmVersion = algorithmVersion;
|
||||||
this.lastUsed = lastUsed;
|
this.lastUsed = lastUsed;
|
||||||
this.siteName = siteName;
|
this.siteName = siteName;
|
||||||
this.siteType = siteType;
|
this.siteType = siteType;
|
||||||
@ -69,12 +68,12 @@ public class MPSite {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MasterKey.Version getMPVersion() {
|
public MasterKey.Version getAlgorithmVersion() {
|
||||||
return mpVersion;
|
return algorithmVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMPVersion(final MasterKey.Version mpVersion) {
|
public void setAlgorithmVersion(final MasterKey.Version mpVersion) {
|
||||||
this.mpVersion = mpVersion;
|
this.algorithmVersion = mpVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instant getLastUsed() {
|
public Instant getLastUsed() {
|
||||||
|
@ -82,7 +82,7 @@ public class MPSiteMarshaller {
|
|||||||
site.getUses(), // uses
|
site.getUses(), // uses
|
||||||
strf( "%d:%d:%d", //
|
strf( "%d:%d:%d", //
|
||||||
site.getSiteType().getType(), // type
|
site.getSiteType().getType(), // type
|
||||||
site.getMPVersion(), // algorithm
|
site.getAlgorithmVersion(), // algorithm
|
||||||
site.getSiteCounter() ), // counter
|
site.getSiteCounter() ), // counter
|
||||||
ifNotNullElse( site.getLoginName(), "" ), // loginName
|
ifNotNullElse( site.getLoginName(), "" ), // loginName
|
||||||
site.getSiteName(), // siteName
|
site.getSiteName(), // siteName
|
||||||
|
Loading…
Reference in New Issue
Block a user