Extract user preferences into a separate class.
This commit is contained in:
parent
0a386d6fad
commit
34042e5462
@ -584,10 +584,13 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener,
|
|||||||
if (fileUser != null) {
|
if (fileUser != null) {
|
||||||
components.add( Components.label( "Default Password Type:" ),
|
components.add( Components.label( "Default Password Type:" ),
|
||||||
Components.comboBox( MPResultType.values(), MPResultType::getLongName,
|
Components.comboBox( MPResultType.values(), MPResultType::getLongName,
|
||||||
fileUser.getDefaultType(), fileUser::setDefaultType ),
|
fileUser.getPreferences().getDefaultType(),
|
||||||
|
fileUser.getPreferences()::setDefaultType ),
|
||||||
Components.strut() );
|
Components.strut() );
|
||||||
|
|
||||||
components.add( Components.checkBox( "Hide Passwords", fileUser.isHidePasswords(), fileUser::setHidePasswords ) );
|
components.add( Components.checkBox( "Hide Passwords",
|
||||||
|
fileUser.getPreferences().isHidePasswords(),
|
||||||
|
fileUser.getPreferences()::setHidePasswords ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Components.showDialog( this, user.getFullName(), new JOptionPane( Components.panel(
|
Components.showDialog( this, user.getFullName(), new JOptionPane( Components.panel(
|
||||||
@ -615,14 +618,14 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener,
|
|||||||
Components.strut() );
|
Components.strut() );
|
||||||
|
|
||||||
components.add( Components.label( "Password Type:" ),
|
components.add( Components.label( "Password Type:" ),
|
||||||
Components.comboBox( MPResultType.values(), type -> getTypeDescription(
|
Components.comboBox( MPResultType.values(), type ->
|
||||||
type, user.getDefaultType(), user.getAlgorithm().mpw_default_result_type() ),
|
getTypeDescription( type, user.getPreferences().getDefaultType() ),
|
||||||
site.getResultType(), site::setResultType ),
|
site.getResultType(), site::setResultType ),
|
||||||
Components.strut() );
|
Components.strut() );
|
||||||
|
|
||||||
components.add( Components.label( "Login Type:" ),
|
components.add( Components.label( "Login Type:" ),
|
||||||
Components.comboBox( MPResultType.values(), type -> getTypeDescription(
|
Components.comboBox( MPResultType.values(), type ->
|
||||||
type, user.getAlgorithm().mpw_default_login_type() ),
|
getTypeDescription( type, user.getAlgorithm().mpw_default_login_type() ),
|
||||||
site.getLoginType(), site::setLoginType ),
|
site.getLoginType(), site::setLoginType ),
|
||||||
Components.strut() );
|
Components.strut() );
|
||||||
|
|
||||||
@ -890,7 +893,7 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener,
|
|||||||
|
|
||||||
if ((result == null) || result.isEmpty())
|
if ((result == null) || result.isEmpty())
|
||||||
resultField.setText( " " );
|
resultField.setText( " " );
|
||||||
else if (!showLogin && (user instanceof MPFileUser) && ((MPFileUser) user).isHidePasswords())
|
else if (!showLogin && user.getPreferences().isHidePasswords())
|
||||||
resultField.setText( EACH_CHARACTER.matcher( result ).replaceAll( "•" ) );
|
resultField.setText( EACH_CHARACTER.matcher( result ).replaceAll( "•" ) );
|
||||||
else
|
else
|
||||||
resultField.setText( result );
|
resultField.setText( result );
|
||||||
@ -1033,8 +1036,8 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener,
|
|||||||
if (!Strings.isNullOrEmpty( queryText ))
|
if (!Strings.isNullOrEmpty( queryText ))
|
||||||
if (siteItems.stream().noneMatch( MPQuery.Result::isExact )) {
|
if (siteItems.stream().noneMatch( MPQuery.Result::isExact )) {
|
||||||
MPQuery.Result<? extends MPSite<?>> selectedItem = sitesModel.getSelectedItem();
|
MPQuery.Result<? extends MPSite<?>> selectedItem = sitesModel.getSelectedItem();
|
||||||
if ((selectedItem != null) && user.equals( selectedItem.getOption().getUser() ) &&
|
if ((selectedItem != null) && user.equals( selectedItem.getValue().getUser() ) &&
|
||||||
queryText.equals( selectedItem.getOption().getSiteName() ))
|
queryText.equals( selectedItem.getValue().getSiteName() ))
|
||||||
siteItems.add( selectedItem );
|
siteItems.add( selectedItem );
|
||||||
else
|
else
|
||||||
siteItems.add( MPQuery.Result.allOf( new MPNewSite( user, query.getQuery() ), query.getQuery() ) );
|
siteItems.add( MPQuery.Result.allOf( new MPNewSite( user, query.getQuery() ), query.getQuery() ) );
|
||||||
|
@ -38,6 +38,9 @@ public interface MPUser<S extends MPSite<?>> extends Comparable<MPUser<?>> {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
String getFullName();
|
String getFullName();
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
MPUserPreferences getPreferences();
|
||||||
|
|
||||||
// - Algorithm
|
// - Algorithm
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -45,11 +48,6 @@ public interface MPUser<S extends MPSite<?>> extends Comparable<MPUser<?>> {
|
|||||||
|
|
||||||
void setAlgorithm(MPAlgorithm algorithm);
|
void setAlgorithm(MPAlgorithm algorithm);
|
||||||
|
|
||||||
@Nullable
|
|
||||||
default MPResultType getDefaultType() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
byte[] getKeyID();
|
byte[] getKeyID();
|
||||||
|
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.lyndir.masterpassword.model;
|
||||||
|
|
||||||
|
import com.lyndir.masterpassword.MPResultType;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lhunath, 2018-10-13
|
||||||
|
*/
|
||||||
|
public interface MPUserPreferences {
|
||||||
|
|
||||||
|
MPResultType getDefaultType();
|
||||||
|
|
||||||
|
void setDefaultType(@Nullable MPResultType defaultType);
|
||||||
|
|
||||||
|
boolean isHidePasswords();
|
||||||
|
|
||||||
|
void setHidePasswords(boolean hidePasswords);
|
||||||
|
}
|
@ -55,8 +55,7 @@ public abstract class MPBasicSite<U extends MPUser<?>, Q extends MPQuestion> ext
|
|||||||
this.siteName = siteName;
|
this.siteName = siteName;
|
||||||
this.algorithm = (algorithm != null)? algorithm: this.user.getAlgorithm();
|
this.algorithm = (algorithm != null)? algorithm: this.user.getAlgorithm();
|
||||||
this.counter = (counter != null)? counter: this.algorithm.mpw_default_counter();
|
this.counter = (counter != null)? counter: this.algorithm.mpw_default_counter();
|
||||||
this.resultType = (resultType != null)? resultType:
|
this.resultType = (resultType != null)? resultType: this.user.getPreferences().getDefaultType();
|
||||||
ifNotNullElse( this.user.getDefaultType(), this.algorithm.mpw_default_result_type() );
|
|
||||||
this.loginType = (loginType != null)? loginType: this.algorithm.mpw_default_login_type();
|
this.loginType = (loginType != null)? loginType: this.algorithm.mpw_default_login_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,12 @@ public abstract class MPBasicUser<S extends MPBasicSite<?, ?>> extends Changeabl
|
|||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public MPUserPreferences getPreferences() {
|
||||||
|
return new MPBasicUserPreferences<MPBasicUser<?>>( this );
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public MPAlgorithm getAlgorithm() {
|
public MPAlgorithm getAlgorithm() {
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.lyndir.masterpassword.model.impl;
|
||||||
|
|
||||||
|
import com.lyndir.masterpassword.MPResultType;
|
||||||
|
import com.lyndir.masterpassword.model.MPUserPreferences;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lhunath, 2018-10-13
|
||||||
|
*/
|
||||||
|
public class MPBasicUserPreferences<U extends MPBasicUser<?>> implements MPUserPreferences {
|
||||||
|
|
||||||
|
private final U user;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private MPResultType defaultType;
|
||||||
|
private boolean hidePasswords;
|
||||||
|
|
||||||
|
public MPBasicUserPreferences(final U user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected U getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MPResultType getDefaultType() {
|
||||||
|
return (defaultType != null)? defaultType: user.getAlgorithm().mpw_default_result_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultType(@Nullable final MPResultType defaultType) {
|
||||||
|
this.defaultType = defaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isHidePasswords() {
|
||||||
|
return hidePasswords;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHidePasswords(final boolean hidePasswords) {
|
||||||
|
this.hidePasswords = hidePasswords;
|
||||||
|
}
|
||||||
|
}
|
@ -20,8 +20,7 @@ package com.lyndir.masterpassword.model.impl;
|
|||||||
|
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import com.lyndir.masterpassword.*;
|
import com.lyndir.masterpassword.*;
|
||||||
import com.lyndir.masterpassword.model.MPIncorrectMasterPasswordException;
|
import com.lyndir.masterpassword.model.*;
|
||||||
import com.lyndir.masterpassword.model.MPUser;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -43,17 +42,16 @@ public class MPFileUser extends MPBasicUser<MPFileSite> {
|
|||||||
private File file;
|
private File file;
|
||||||
private MPMarshalFormat format;
|
private MPMarshalFormat format;
|
||||||
private MPMarshaller.ContentMode contentMode;
|
private MPMarshaller.ContentMode contentMode;
|
||||||
|
private ReadableInstant lastUsed;
|
||||||
|
private boolean complete;
|
||||||
|
|
||||||
private MPResultType defaultType;
|
private final MPFileUserPreferences preferences;
|
||||||
private ReadableInstant lastUsed;
|
|
||||||
private boolean hidePasswords;
|
|
||||||
private boolean complete;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static MPFileUser load(final File file)
|
public static MPFileUser load(final File file)
|
||||||
throws IOException, MPMarshalException {
|
throws IOException, MPMarshalException {
|
||||||
for (final MPMarshalFormat format : MPMarshalFormat.values())
|
for (final MPMarshalFormat format : MPMarshalFormat.values())
|
||||||
if (format.matches(file))
|
if (format.matches( file ))
|
||||||
return format.unmarshaller().readUser( file );
|
return format.unmarshaller().readUser( file );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -74,9 +72,8 @@ public class MPFileUser extends MPBasicUser<MPFileSite> {
|
|||||||
super( avatar, fullName, algorithm );
|
super( avatar, fullName, algorithm );
|
||||||
|
|
||||||
this.keyID = (keyID != null)? keyID.clone(): null;
|
this.keyID = (keyID != null)? keyID.clone(): null;
|
||||||
this.defaultType = (defaultType != null)? defaultType: algorithm.mpw_default_result_type();
|
|
||||||
this.lastUsed = lastUsed;
|
this.lastUsed = lastUsed;
|
||||||
this.hidePasswords = hidePasswords;
|
this.preferences = new MPFileUserPreferences( this, defaultType, hidePasswords );
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.contentMode = contentMode;
|
this.contentMode = contentMode;
|
||||||
|
|
||||||
@ -92,6 +89,12 @@ public class MPFileUser extends MPBasicUser<MPFileSite> {
|
|||||||
return (keyID == null)? null: keyID.clone();
|
return (keyID == null)? null: keyID.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public MPUserPreferences getPreferences() {
|
||||||
|
return preferences;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAlgorithm(final MPAlgorithm algorithm) {
|
public void setAlgorithm(final MPAlgorithm algorithm) {
|
||||||
if (!algorithm.equals( getAlgorithm() ) && (keyID != null)) {
|
if (!algorithm.equals( getAlgorithm() ) && (keyID != null)) {
|
||||||
@ -128,19 +131,6 @@ public class MPFileUser extends MPBasicUser<MPFileSite> {
|
|||||||
setChanged();
|
setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MPResultType getDefaultType() {
|
|
||||||
return defaultType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultType(final MPResultType defaultType) {
|
|
||||||
if (this.defaultType == defaultType)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.defaultType = defaultType;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadableInstant getLastUsed() {
|
public ReadableInstant getLastUsed() {
|
||||||
return lastUsed;
|
return lastUsed;
|
||||||
}
|
}
|
||||||
@ -150,18 +140,6 @@ public class MPFileUser extends MPBasicUser<MPFileSite> {
|
|||||||
setChanged();
|
setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHidePasswords() {
|
|
||||||
return hidePasswords;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHidePasswords(final boolean hidePasswords) {
|
|
||||||
if (Objects.equals( this.hidePasswords, hidePasswords ))
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.hidePasswords = hidePasswords;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isComplete() {
|
protected boolean isComplete() {
|
||||||
return complete;
|
return complete;
|
||||||
}
|
}
|
||||||
@ -193,7 +171,7 @@ public class MPFileUser extends MPBasicUser<MPFileSite> {
|
|||||||
*/
|
*/
|
||||||
public void migrateTo(final File path, final MPMarshalFormat newFormat) {
|
public void migrateTo(final File path, final MPMarshalFormat newFormat) {
|
||||||
MPMarshalFormat oldFormat = format;
|
MPMarshalFormat oldFormat = format;
|
||||||
File oldFile = file, newFile = new File( path, getFullName() + newFormat.fileSuffix() );
|
File oldFile = file, newFile = new File( path, getFullName() + newFormat.fileSuffix() );
|
||||||
|
|
||||||
// If the format hasn't changed, migrate by moving the file: the contents doesn't need to change.
|
// If the format hasn't changed, migrate by moving the file: the contents doesn't need to change.
|
||||||
if ((oldFormat == newFormat) && !oldFile.equals( newFile ) && oldFile.exists())
|
if ((oldFormat == newFormat) && !oldFile.equals( newFile ) && oldFile.exists())
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.lyndir.masterpassword.model.impl;
|
||||||
|
|
||||||
|
import com.lyndir.masterpassword.MPResultType;
|
||||||
|
import java.util.Objects;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lhunath, 2018-10-13
|
||||||
|
*/
|
||||||
|
public class MPFileUserPreferences extends MPBasicUserPreferences<MPFileUser> {
|
||||||
|
|
||||||
|
public MPFileUserPreferences(final MPFileUser user, @Nullable final MPResultType defaultType, final boolean hidePasswords) {
|
||||||
|
super( user );
|
||||||
|
|
||||||
|
setDefaultType( defaultType );
|
||||||
|
setHidePasswords( hidePasswords );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultType(@Nullable final MPResultType defaultType) {
|
||||||
|
if (getDefaultType() == defaultType)
|
||||||
|
return;
|
||||||
|
|
||||||
|
super.setDefaultType( defaultType );
|
||||||
|
getUser().setChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHidePasswords(final boolean hidePasswords) {
|
||||||
|
if (Objects.equals( isHidePasswords(), hidePasswords ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
super.setHidePasswords( hidePasswords );
|
||||||
|
getUser().setChanged();
|
||||||
|
}
|
||||||
|
}
|
@ -56,7 +56,7 @@ public class MPFlatMarshaller implements MPMarshaller {
|
|||||||
content.append( "# Avatar: " ).append( user.getAvatar() ).append( '\n' );
|
content.append( "# Avatar: " ).append( user.getAvatar() ).append( '\n' );
|
||||||
content.append( "# Key ID: " ).append( user.exportKeyID() ).append( '\n' );
|
content.append( "# Key ID: " ).append( user.exportKeyID() ).append( '\n' );
|
||||||
content.append( "# Algorithm: " ).append( user.getAlgorithm().version().toInt() ).append( '\n' );
|
content.append( "# Algorithm: " ).append( user.getAlgorithm().version().toInt() ).append( '\n' );
|
||||||
content.append( "# Default Type: " ).append( user.getDefaultType().getType() ).append( '\n' );
|
content.append( "# Default Type: " ).append( user.getPreferences().getDefaultType().getType() ).append( '\n' );
|
||||||
content.append( "# Passwords: " ).append( user.getContentMode().name() ).append( '\n' );
|
content.append( "# Passwords: " ).append( user.getContentMode().name() ).append( '\n' );
|
||||||
content.append( "##\n" );
|
content.append( "##\n" );
|
||||||
content.append( "#\n" );
|
content.append( "#\n" );
|
||||||
|
@ -77,10 +77,10 @@ public class MPJSONFile extends MPJSONAnyObject {
|
|||||||
user.avatar = modelUser.getAvatar();
|
user.avatar = modelUser.getAvatar();
|
||||||
user.full_name = modelUser.getFullName();
|
user.full_name = modelUser.getFullName();
|
||||||
user.last_used = MPModelConstants.dateTimeFormatter.print( modelUser.getLastUsed() );
|
user.last_used = MPModelConstants.dateTimeFormatter.print( modelUser.getLastUsed() );
|
||||||
user.hide_passwords = modelUser.isHidePasswords();
|
|
||||||
user.key_id = modelUser.exportKeyID();
|
user.key_id = modelUser.exportKeyID();
|
||||||
user.algorithm = modelUser.getAlgorithm().version();
|
user.algorithm = modelUser.getAlgorithm().version();
|
||||||
user.default_type = modelUser.getDefaultType();
|
user.default_type = modelUser.getPreferences().getDefaultType();
|
||||||
|
user.hide_passwords = modelUser.getPreferences().isHidePasswords();
|
||||||
|
|
||||||
// Section "sites"
|
// Section "sites"
|
||||||
sites = new LinkedHashMap<>();
|
sites = new LinkedHashMap<>();
|
||||||
|
Loading…
Reference in New Issue
Block a user