2
0

Deep Java refactoring to match the C API logic and clean up some OO oddities.

This commit is contained in:
Maarten Billemont
2017-09-22 19:03:50 -04:00
parent dc7089c38c
commit 5d1be43b65
42 changed files with 823 additions and 1157 deletions

View File

@@ -24,7 +24,6 @@ import com.google.common.io.*;
import com.lyndir.lhunath.opal.system.logging.Logger;
import com.lyndir.lhunath.opal.system.util.TypeUtils;
import com.lyndir.masterpassword.gui.model.User;
import com.lyndir.masterpassword.gui.view.PasswordFrame;
import com.lyndir.masterpassword.gui.view.UnlockFrame;
import java.io.*;
@@ -46,7 +45,7 @@ public class GUI implements UnlockFrame.SignInCallback {
private static final Logger logger = Logger.get( GUI.class );
private final UnlockFrame unlockFrame = new UnlockFrame( this );
private PasswordFrame passwordFrame;
private PasswordFrame<?, ?> passwordFrame;
public static void main(final String... args) {
@@ -104,12 +103,8 @@ public class GUI implements UnlockFrame.SignInCallback {
}
@Override
public void signedIn(final User user) {
passwordFrame = newPasswordFrame( user );
public void signedIn(final PasswordFrame<?, ?> passwordFrame) {
this.passwordFrame = passwordFrame;
open();
}
protected PasswordFrame newPasswordFrame(final User user) {
return new PasswordFrame( user );
}
}

View File

@@ -20,21 +20,22 @@ package com.lyndir.masterpassword.gui.model;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.masterpassword.MPResultType;
import com.lyndir.masterpassword.MasterKey;
import com.lyndir.masterpassword.MPMasterKey;
import com.lyndir.masterpassword.model.MPSite;
/**
* @author lhunath, 14-12-16
*/
public class IncognitoSite extends Site {
public class IncognitoSite extends MPSite {
private String siteName;
private UnsignedInteger siteCounter;
private MPResultType resultType;
private MasterKey.Version algorithmVersion;
private String siteName;
private UnsignedInteger siteCounter;
private MPResultType resultType;
private MPMasterKey.Version algorithmVersion;
public IncognitoSite(final String siteName, final UnsignedInteger siteCounter, final MPResultType resultType,
final MasterKey.Version algorithmVersion) {
final MPMasterKey.Version algorithmVersion) {
this.siteName = siteName;
this.siteCounter = siteCounter;
this.resultType = resultType;
@@ -62,12 +63,12 @@ public class IncognitoSite extends Site {
}
@Override
public MasterKey.Version getAlgorithmVersion() {
public MPMasterKey.Version getAlgorithmVersion() {
return algorithmVersion;
}
@Override
public void setAlgorithmVersion(final MasterKey.Version algorithmVersion) {
public void setAlgorithmVersion(final MPMasterKey.Version algorithmVersion) {
this.algorithmVersion = algorithmVersion;
}

View File

@@ -19,15 +19,17 @@
package com.lyndir.masterpassword.gui.model;
import com.google.common.collect.ImmutableList;
import com.lyndir.masterpassword.MasterKey;
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
import javax.annotation.Nullable;
import com.lyndir.masterpassword.MPMasterKey;
import com.lyndir.masterpassword.model.MPIncorrectMasterPasswordException;
import com.lyndir.masterpassword.model.MPUser;
import java.util.Collection;
import javax.annotation.Nonnull;
/**
* @author lhunath, 2014-06-08
*/
public class IncognitoUser extends User {
public class IncognitoUser extends MPUser<IncognitoSite> {
private final String fullName;
@@ -41,21 +43,27 @@ public class IncognitoUser extends User {
}
@Override
public void authenticate(final char[] masterPassword)
throws IncorrectMasterPasswordException {
this.key = new MasterKey( getFullName(), masterPassword );
public MPMasterKey.Version getAlgorithmVersion() {
return MPMasterKey.Version.CURRENT;
}
@Override
public Iterable<Site> findSitesByName(final String siteName) {
public void addSite(final IncognitoSite site) {
}
@Override
public void deleteSite(final IncognitoSite site) {
}
@Override
public Collection<IncognitoSite> findSites(final String query) {
return ImmutableList.of();
}
@Nonnull
@Override
public void addSite(final Site site) {
}
@Override
public void deleteSite(final Site site) {
public MPMasterKey authenticate(final char[] masterPassword)
throws MPIncorrectMasterPasswordException {
return key = new MPMasterKey( getFullName(), masterPassword );
}
}

View File

@@ -1,96 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Master Password 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 General Public License for more details.
//
// You can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.gui.model;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.masterpassword.MPResultType;
import com.lyndir.masterpassword.MasterKey;
import com.lyndir.masterpassword.model.*;
/**
* @author lhunath, 14-12-16
*/
public class ModelSite extends Site {
private final MPSite model;
public ModelSite(final MPSiteResult result) {
model = result.getSite();
}
public MPSite getModel() {
return model;
}
@Override
public String getSiteName() {
return model.getSiteName();
}
@Override
public void setSiteName(final String siteName) {
model.setSiteName( siteName );
MPUserFileManager.get().save();
}
@Override
public MPResultType getResultType() {
return model.getResultType();
}
@Override
public void setResultType(final MPResultType resultType) {
if (resultType != getResultType()) {
model.setResultType( resultType );
MPUserFileManager.get().save();
}
}
@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();
}
}
@Override
public UnsignedInteger getSiteCounter() {
return model.getSiteCounter();
}
@Override
public void setSiteCounter(final UnsignedInteger siteCounter) {
if (siteCounter.equals( getSiteCounter() )) {
model.setSiteCounter( siteCounter );
MPUserFileManager.get().save();
}
}
public void use() {
model.updateLastUsed();
MPUserFileManager.get().save();
}
}

View File

@@ -1,97 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Master Password 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 General Public License for more details.
//
// You can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.gui.model;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.FluentIterable;
import com.lyndir.masterpassword.gui.*;
import com.lyndir.masterpassword.model.*;
import java.util.Arrays;
import javax.annotation.Nullable;
/**
* @author lhunath, 14-12-08
*/
public class ModelUser extends User {
private final MPUser model;
public ModelUser(final MPUser model) {
this.model = model;
}
public MPUser getModel() {
return model;
}
@Override
public String getFullName() {
return model.getFullName();
}
@Override
public int getAvatar() {
return model.getAvatar();
}
public void setAvatar(final int avatar) {
model.setAvatar( avatar % Res.avatars());
MPUserFileManager.get().save();
}
@Override
public void authenticate(final char[] masterPassword)
throws IncorrectMasterPasswordException {
key = model.authenticate( masterPassword );
MPUserFileManager.get().save();
}
@Override
public Iterable<Site> findSitesByName(final String siteName) {
return FluentIterable.from( model.findSitesByName( siteName ) ).transform( new Function<MPSiteResult, Site>() {
@Nullable
@Override
public Site apply(@Nullable final MPSiteResult site) {
return new ModelSite( Preconditions.checkNotNull( site ) );
}
} );
}
@Override
public void addSite(final Site site) {
model.addSite( new MPSite( model, site.getSiteName(), site.getSiteCounter(), site.getResultType() ) );
model.updateLastUsed();
MPUserFileManager.get().save();
}
@Override
public void deleteSite(final Site site) {
if (site instanceof ModelSite) {
model.deleteSite(((ModelSite) site).getModel());
MPUserFileManager.get().save();
}
}
public boolean keySaved() {
// TODO
return false;
}
}

View File

@@ -1,53 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Master Password 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 General Public License for more details.
//
// You can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.gui.model;
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.masterpassword.MPResultType;
import com.lyndir.masterpassword.MasterKey;
/**
* @author lhunath, 14-12-16
*/
public abstract class Site {
public abstract String getSiteName();
public abstract void setSiteName(String siteName);
public abstract MPResultType getResultType();
public abstract void setResultType(MPResultType resultType);
public abstract MasterKey.Version getAlgorithmVersion();
public abstract void setAlgorithmVersion(MasterKey.Version algorithmVersion);
public abstract UnsignedInteger getSiteCounter();
public abstract void setSiteCounter(UnsignedInteger siteCounter);
@Override
public String toString() {
return strf( "{%s: %s}", getClass().getSimpleName(), getSiteName() );
}
}

View File

@@ -1,76 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Master Password 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 General Public License for more details.
//
// You can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.gui.model;
import com.google.common.base.Preconditions;
import com.lyndir.masterpassword.MasterKey;
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
import java.util.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* @author lhunath, 2014-06-08
*/
public abstract class User {
@Nullable
protected MasterKey key;
public abstract String getFullName();
@SuppressWarnings("MethodCanBeVariableArityMethod")
public abstract void authenticate(char[] masterPassword)
throws IncorrectMasterPasswordException;
public int getAvatar() {
return 0;
}
public boolean isKeyAvailable() {
return key != null;
}
@Nonnull
public MasterKey getKey() {
return Preconditions.checkNotNull( key, "User is not authenticated: " + getFullName() );
}
public abstract Iterable<Site> findSitesByName(String siteName);
public abstract void addSite(Site site);
public abstract void deleteSite(Site site);
@Override
public boolean equals(final Object obj) {
return (this == obj) || ((obj instanceof User) && Objects.equals( getFullName(), ((User) obj).getFullName() ));
}
@Override
public int hashCode() {
return Objects.hashCode( getFullName() );
}
@Override
public String toString() {
return getFullName();
}
}

View File

@@ -21,7 +21,7 @@ package com.lyndir.masterpassword.gui.platform.mac;
import com.apple.eawt.*;
import com.lyndir.masterpassword.gui.GUI;
import com.lyndir.masterpassword.gui.view.PasswordFrame;
import com.lyndir.masterpassword.gui.model.User;
import com.lyndir.masterpassword.model.MPUser;
import javax.swing.*;
@@ -52,12 +52,4 @@ public class AppleGUI extends GUI {
}
} );
}
@Override
protected PasswordFrame newPasswordFrame(final User user) {
PasswordFrame frame = super.newPasswordFrame( user );
frame.setDefaultCloseOperation( WindowConstants.HIDE_ON_CLOSE );
return frame;
}
}

View File

@@ -20,9 +20,8 @@ package com.lyndir.masterpassword.gui.view;
import com.google.common.collect.ImmutableList;
import com.lyndir.masterpassword.gui.Res;
import com.lyndir.masterpassword.gui.model.User;
import com.lyndir.masterpassword.model.MPUser;
import com.lyndir.masterpassword.gui.util.Components;
import com.lyndir.masterpassword.gui.view.UnlockFrame;
import java.awt.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -32,7 +31,7 @@ import javax.swing.*;
/**
* @author lhunath, 2014-06-11
*/
public abstract class AuthenticationPanel extends Components.GradientPanel {
public abstract class AuthenticationPanel<U extends MPUser<?>> extends Components.GradientPanel {
protected final UnlockFrame unlockFrame;
protected final JLabel avatarLabel;
@@ -65,11 +64,12 @@ public abstract class AuthenticationPanel extends Components.GradientPanel {
}
@Nullable
protected abstract User getSelectedUser();
protected abstract U getSelectedUser();
@Nonnull
public abstract char[] getMasterPassword();
@Nullable
public Component getFocusComponent() {
return null;
}
@@ -79,4 +79,6 @@ public abstract class AuthenticationPanel extends Components.GradientPanel {
}
public abstract void reset();
public abstract PasswordFrame<?, ?> newPasswordFrame();
}

View File

@@ -18,9 +18,12 @@
package com.lyndir.masterpassword.gui.view;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.masterpassword.MPMasterKey;
import com.lyndir.masterpassword.MPResultType;
import com.lyndir.masterpassword.gui.Res;
import com.lyndir.masterpassword.gui.model.IncognitoSite;
import com.lyndir.masterpassword.gui.model.IncognitoUser;
import com.lyndir.masterpassword.gui.model.User;
import com.lyndir.masterpassword.gui.util.Components;
import java.awt.*;
import java.awt.event.ActionEvent;
@@ -34,7 +37,8 @@ import javax.swing.event.DocumentListener;
/**
* @author lhunath, 2014-06-11
*/
public class IncognitoAuthenticationPanel extends AuthenticationPanel implements DocumentListener, ActionListener {
@SuppressWarnings({ "serial", "MagicNumber" })
public class IncognitoAuthenticationPanel extends AuthenticationPanel<IncognitoUser> implements DocumentListener, ActionListener {
private final JTextField fullNameField;
private final JPasswordField masterPasswordField;
@@ -76,7 +80,19 @@ public class IncognitoAuthenticationPanel extends AuthenticationPanel implements
}
@Override
protected User getSelectedUser() {
public PasswordFrame<IncognitoUser, ?> newPasswordFrame() {
return new PasswordFrame<IncognitoUser, IncognitoSite>(getSelectedUser()) {
@Override
protected IncognitoSite createSite(final IncognitoUser user, final String siteName, final UnsignedInteger siteCounter,
final MPResultType resultType,
final MPMasterKey.Version algorithmVersion) {
return new IncognitoSite( siteName, siteCounter, resultType, algorithmVersion );
}
};
}
@Override
protected IncognitoUser getSelectedUser() {
return new IncognitoUser( fullNameField.getText() );
}

View File

@@ -20,19 +20,17 @@ package com.lyndir.masterpassword.gui.view;
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.*;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.lhunath.opal.system.logging.Logger;
import com.lyndir.masterpassword.MPMasterKey;
import com.lyndir.masterpassword.MPResultType;
import com.lyndir.masterpassword.gui.Res;
import com.lyndir.masterpassword.gui.model.ModelUser;
import com.lyndir.masterpassword.model.MPUser;
import com.lyndir.masterpassword.model.MPUserFileManager;
import com.lyndir.masterpassword.model.*;
import com.lyndir.masterpassword.gui.util.Components;
import java.awt.*;
import java.awt.event.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
@@ -47,7 +45,7 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
@SuppressWarnings("UnusedDeclaration")
private static final Logger logger = Logger.get( ModelAuthenticationPanel.class );
private final JComboBox<ModelUser> userField;
private final JComboBox<MPFileUser> userField;
private final JLabel masterPasswordLabel;
private final JPasswordField masterPasswordField;
@@ -59,7 +57,7 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
avatarLabel.addMouseListener( new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
ModelUser selectedUser = getSelectedUser();
MPFileUser selectedUser = getSelectedUser();
if (selectedUser != null) {
selectedUser.setAvatar( selectedUser.getAvatar() + 1 );
updateUser( false );
@@ -104,10 +102,10 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
@Override
protected void updateUser(boolean repack) {
ModelUser selectedUser = getSelectedUser();
MPFileUser selectedUser = getSelectedUser();
if (selectedUser != null) {
avatarLabel.setIcon( Res.avatar( selectedUser.getAvatar() ) );
boolean showPasswordField = !selectedUser.keySaved();
boolean showPasswordField = !selectedUser.isMasterKeyAvailable(); // TODO: is this the same as keySaved()?
if (masterPasswordField.isVisible() != showPasswordField) {
masterPasswordLabel.setVisible( showPasswordField );
masterPasswordField.setVisible( showPasswordField );
@@ -119,7 +117,7 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
}
@Override
protected ModelUser getSelectedUser() {
protected MPFileUser getSelectedUser() {
int selectedIndex = userField.getSelectedIndex();
if (selectedIndex < 0)
return null;
@@ -143,7 +141,7 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
String fullName = JOptionPane.showInputDialog( ModelAuthenticationPanel.this, //
"Enter your full name, ensuring it is correctly spelled and capitalized:",
"New User", JOptionPane.QUESTION_MESSAGE );
MPUserFileManager.get().addUser( new MPUser( fullName ) );
MPFileUserManager.get().addUser( new MPFileUser( fullName ) );
userField.setModel( new DefaultComboBoxModel<>( readConfigUsers() ) );
updateUser( true );
}
@@ -155,7 +153,7 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
addActionListener( new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
ModelUser deleteUser = getSelectedUser();
MPFileUser deleteUser = getSelectedUser();
if (deleteUser == null)
return;
@@ -165,7 +163,7 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
"Delete User", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ) == JOptionPane.CANCEL_OPTION)
return;
MPUserFileManager.get().deleteUser( deleteUser.getModel() );
MPFileUserManager.get().deleteUser( deleteUser );
userField.setModel( new DefaultComboBoxModel<>( readConfigUsers() ) );
updateUser( true );
}
@@ -179,7 +177,7 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
public void actionPerformed(final ActionEvent e) {
JOptionPane.showMessageDialog( ModelAuthenticationPanel.this, //
strf( "Reads users and sites from the directory at:\n%s",
MPUserFileManager.get().getPath().getAbsolutePath() ), //
MPFileUserManager.get().getPath().getAbsolutePath() ), //
"Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
@@ -193,14 +191,19 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
masterPasswordField.setText( "" );
}
private static ModelUser[] readConfigUsers() {
return FluentIterable.from( MPUserFileManager.get().getUsers() ).transform( new Function<MPUser, ModelUser>() {
@Nullable
@Override
public PasswordFrame<MPFileUser, MPFileSite> newPasswordFrame() {
return new PasswordFrame<MPFileUser, MPFileSite>(getSelectedUser()) {
@Override
public ModelUser apply(@Nullable final MPUser model) {
return new ModelUser( Preconditions.checkNotNull( model ) );
protected MPFileSite createSite(final MPFileUser user, final String siteName, final UnsignedInteger siteCounter, final MPResultType resultType,
final MPMasterKey.Version algorithmVersion) {
return new MPFileSite( user, siteName, siteCounter, resultType, algorithmVersion );
}
} ).toArray( ModelUser.class );
};
}
private static MPFileUser[] readConfigUsers() {
return MPFileUserManager.get().getUsers().toArray( new MPFileUser[0] );
}
@Override

View File

@@ -26,11 +26,12 @@ import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.util.concurrent.*;
import com.lyndir.lhunath.opal.system.util.ObjectUtils;
import com.lyndir.masterpassword.*;
import com.lyndir.masterpassword.gui.Res;
import com.lyndir.masterpassword.gui.model.*;
import com.lyndir.masterpassword.gui.util.Components;
import com.lyndir.masterpassword.gui.util.UnsignedIntegerModel;
import com.lyndir.masterpassword.model.*;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.*;
@@ -44,28 +45,28 @@ import javax.swing.event.*;
/**
* @author lhunath, 2014-06-08
*/
public class PasswordFrame extends JFrame implements DocumentListener {
public abstract class PasswordFrame<U extends MPUser<S>, S extends MPSite> extends JFrame implements DocumentListener {
@SuppressWarnings("FieldCanBeLocal")
private final Components.GradientPanel root;
private final JTextField siteNameField;
private final JButton siteActionButton;
private final JComboBox<MasterKey.Version> siteVersionField;
private final JSpinner siteCounterField;
private final UnsignedIntegerModel siteCounterModel;
private final JComboBox<MPResultType> resultTypeField;
private final JPasswordField passwordField;
private final JLabel tipLabel;
private final JCheckBox maskPasswordField;
private final char passwordEchoChar;
private final Font passwordEchoFont;
private final User user;
private final Components.GradientPanel root;
private final JTextField siteNameField;
private final JButton siteActionButton;
private final JComboBox<MPMasterKey.Version> siteVersionField;
private final JSpinner siteCounterField;
private final UnsignedIntegerModel siteCounterModel;
private final JComboBox<MPResultType> resultTypeField;
private final JPasswordField passwordField;
private final JLabel tipLabel;
private final JCheckBox maskPasswordField;
private final char passwordEchoChar;
private final Font passwordEchoFont;
private final U user;
@Nullable
private Site currentSite;
private S currentSite;
private boolean updatingUI;
public PasswordFrame(final User user) {
public PasswordFrame(final U user) {
super( "Master Password" );
this.user = user;
@@ -122,7 +123,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
public void actionPerformed(final ActionEvent e) {
if (currentSite == null)
return;
if (currentSite instanceof ModelSite)
if (currentSite instanceof MPFileSite)
PasswordFrame.this.user.deleteSite( currentSite );
else
PasswordFrame.this.user.addSite( currentSite );
@@ -140,7 +141,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
JComponent siteSettings = Components.boxLayout( BoxLayout.LINE_AXIS, //
resultTypeField = Components.comboBox( types ), //
Components.stud(), //
siteVersionField = Components.comboBox( MasterKey.Version.values() ), //
siteVersionField = Components.comboBox( MPMasterKey.Version.values() ), //
Components.stud(), //
siteCounterField = Components.spinner( siteCounterModel ) );
sitePanel.add( siteSettings );
@@ -155,7 +156,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
siteVersionField.setFont( Res.valueFont().deriveFont( 12f ) );
siteVersionField.setAlignmentX( RIGHT_ALIGNMENT );
siteVersionField.setSelectedItem( MasterKey.Version.CURRENT );
siteVersionField.setSelectedItem( MPMasterKey.Version.CURRENT );
siteVersionField.addItemListener( new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
@@ -226,27 +227,27 @@ public class PasswordFrame extends JFrame implements DocumentListener {
final String siteNameQuery = siteNameField.getText();
if (updatingUI)
return Futures.immediateCancelledFuture();
if ((siteNameQuery == null) || siteNameQuery.isEmpty() || !user.isKeyAvailable()) {
if ((siteNameQuery == null) || siteNameQuery.isEmpty() || !user.isMasterKeyAvailable()) {
siteActionButton.setVisible( false );
tipLabel.setText( null );
passwordField.setText( null );
return Futures.immediateCancelledFuture();
}
MPResultType resultType = resultTypeField.getModel().getElementAt( resultTypeField.getSelectedIndex() );
MasterKey.Version siteVersion = siteVersionField.getItemAt( siteVersionField.getSelectedIndex() );
UnsignedInteger siteCounter = siteCounterModel.getNumber();
MPResultType resultType = resultTypeField.getModel().getElementAt( resultTypeField.getSelectedIndex() );
MPMasterKey.Version siteVersion = siteVersionField.getItemAt( siteVersionField.getSelectedIndex() );
UnsignedInteger siteCounter = siteCounterModel.getNumber();
Iterable<Site> siteResults = user.findSitesByName( siteNameQuery );
Iterable<S> siteResults = user.findSites( siteNameQuery );
if (!allowNameCompletion)
siteResults = FluentIterable.from( siteResults ).filter( new Predicate<Site>() {
siteResults = FluentIterable.from( siteResults ).filter( new Predicate<S>() {
@Override
public boolean apply(@Nullable final Site siteResult) {
public boolean apply(@Nullable final S siteResult) {
return (siteResult != null) && siteNameQuery.equals( siteResult.getSiteName() );
}
} );
final Site site = ifNotNullElse( Iterables.getFirst( siteResults, null ),
new IncognitoSite( siteNameQuery, siteCounter, resultType, siteVersion ) );
final S site = ifNotNullElse( Iterables.getFirst( siteResults, null ),
createSite( user, siteNameQuery, siteCounter, resultType, siteVersion ) );
if ((currentSite != null) && currentSite.getSiteName().equals( site.getSiteName() )) {
site.setResultType( resultType );
site.setAlgorithmVersion( siteVersion );
@@ -257,8 +258,9 @@ public class PasswordFrame extends JFrame implements DocumentListener {
@Override
public String call()
throws Exception {
return user.getKey()
.siteResult( site.getSiteName(), site.getSiteCounter(), MPKeyPurpose.Authentication, null, site.getResultType(), null, site.getAlgorithmVersion() );
return user.getMasterKey()
.siteResult( site.getSiteName(), site.getSiteCounter(), MPKeyPurpose.Authentication, null, site.getResultType(),
null, site.getAlgorithmVersion() );
}
} );
Futures.addCallback( passwordFuture, new FutureCallback<String>() {
@@ -269,8 +271,8 @@ public class PasswordFrame extends JFrame implements DocumentListener {
public void run() {
updatingUI = true;
currentSite = site;
siteActionButton.setVisible( user instanceof ModelUser );
if (currentSite instanceof ModelSite)
siteActionButton.setVisible( user instanceof MPFileUser );
if (currentSite instanceof MPFileSite)
siteActionButton.setText( "Delete Site" );
else
siteActionButton.setText( "Add Site" );
@@ -296,6 +298,9 @@ public class PasswordFrame extends JFrame implements DocumentListener {
return passwordFuture;
}
protected abstract S createSite(U user, String siteName, UnsignedInteger siteCounter, MPResultType resultType,
MPMasterKey.Version algorithmVersion);
@Override
public void insertUpdate(final DocumentEvent e) {
updatePassword( true );

View File

@@ -22,9 +22,9 @@ import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
import com.lyndir.masterpassword.MPIdenticon;
import com.lyndir.masterpassword.gui.*;
import com.lyndir.masterpassword.gui.model.User;
import com.lyndir.masterpassword.model.MPUser;
import com.lyndir.masterpassword.gui.util.Components;
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
import com.lyndir.masterpassword.model.MPIncorrectMasterPasswordException;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.Future;
@@ -36,6 +36,7 @@ import javax.swing.*;
/**
* @author lhunath, 2014-06-08
*/
@SuppressWarnings({ "MagicNumber", "serial" })
public class UnlockFrame extends JFrame {
private final SignInCallback signInCallback;
@@ -43,10 +44,10 @@ public class UnlockFrame extends JFrame {
private final JLabel identiconLabel;
private final JButton signInButton;
private final JPanel authenticationContainer;
private AuthenticationPanel authenticationPanel;
private AuthenticationPanel<?> authenticationPanel;
private Future<?> identiconFuture;
private boolean incognito;
private User user;
private MPUser<?> user;
public UnlockFrame(final SignInCallback signInCallback) {
super( "Unlock Master Password" );
@@ -155,7 +156,7 @@ public class UnlockFrame extends JFrame {
} );
}
void updateUser(@Nullable final User user) {
void updateUser(@Nullable final MPUser<?> user) {
this.user = user;
checkSignIn();
}
@@ -213,12 +214,12 @@ public class UnlockFrame extends JFrame {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
signInCallback.signedIn( user );
signInCallback.signedIn( authenticationPanel.newPasswordFrame() );
dispose();
}
} );
}
catch (final IncorrectMasterPasswordException e) {
catch (final MPIncorrectMasterPasswordException e) {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
@@ -237,6 +238,6 @@ public class UnlockFrame extends JFrame {
public interface SignInCallback {
void signedIn(User user);
void signedIn(PasswordFrame<?, ?> passwordFrame);
}
}