Initial implementation of questions support.
This commit is contained in:
parent
38a357cb28
commit
8d7c351912
@ -66,6 +66,11 @@ public abstract class MPAlgorithm {
|
||||
*/
|
||||
public abstract MPResultType mpw_default_login_type();
|
||||
|
||||
/**
|
||||
* mpw: defaults: answer result type.
|
||||
*/
|
||||
public abstract MPResultType mpw_default_answer_type();
|
||||
|
||||
/**
|
||||
* mpw: defaults: initial counter value.
|
||||
*/
|
||||
|
@ -256,6 +256,11 @@ public class MPAlgorithmV0 extends MPAlgorithm {
|
||||
return MPResultType.GeneratedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPResultType mpw_default_answer_type() {
|
||||
return MPResultType.GeneratedPhrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnsignedInteger mpw_default_counter() {
|
||||
return UnsignedInteger.ONE;
|
||||
|
@ -0,0 +1,84 @@
|
||||
//==============================================================================
|
||||
// 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.model;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.ifNotNullElse;
|
||||
|
||||
import com.lyndir.masterpassword.*;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
/**
|
||||
* @author lhunath, 2018-05-14
|
||||
*/
|
||||
public class MPFileQuestion extends MPQuestion {
|
||||
|
||||
private final MPSite site;
|
||||
|
||||
private String keyword;
|
||||
@Nullable
|
||||
private String state;
|
||||
private MPResultType type;
|
||||
|
||||
public MPFileQuestion(final MPSite site, final String keyword, @Nullable final String state, @Nullable final MPResultType type) {
|
||||
this.site = site;
|
||||
this.keyword = keyword;
|
||||
this.state = state;
|
||||
this.type = ifNotNullElse( type, site.getAlgorithm().mpw_default_answer_type() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPSite getSite() {
|
||||
return site;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public void setKeyword(final String keyword) {
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
public void setAnswer(final MPResultType type, @Nullable final String answer)
|
||||
throws MPKeyUnavailableException {
|
||||
this.type = type;
|
||||
|
||||
if (answer == null)
|
||||
this.state = null;
|
||||
else
|
||||
this.state = getSite().getState(
|
||||
MPKeyPurpose.Recovery, getKeyword(), null, type, answer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPResultType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final MPResultType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getAnswer()
|
||||
throws MPKeyUnavailableException {
|
||||
return getAnswer( state );
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
||||
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.lyndir.masterpassword.*;
|
||||
import java.util.*;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.time.Instant;
|
||||
@ -36,9 +37,9 @@ public class MPFileSite extends MPSite {
|
||||
private final MPFileUser user;
|
||||
|
||||
private String siteName;
|
||||
private UnsignedInteger siteCounter;
|
||||
@Nullable
|
||||
private String siteState;
|
||||
private UnsignedInteger siteCounter;
|
||||
private MPResultType resultType;
|
||||
private MPAlgorithm algorithm;
|
||||
|
||||
@ -51,6 +52,8 @@ public class MPFileSite extends MPSite {
|
||||
private int uses;
|
||||
private ReadableInstant lastUsed;
|
||||
|
||||
private final Collection<MPFileQuestion> questions = new LinkedHashSet<>();
|
||||
|
||||
public MPFileSite(final MPFileUser user, final String siteName) {
|
||||
this( user, siteName, null, null, user.getAlgorithm() );
|
||||
}
|
||||
@ -66,11 +69,12 @@ public class MPFileSite extends MPSite {
|
||||
@Nullable final String loginState, @Nullable final MPResultType loginType,
|
||||
@Nullable final String url, final int uses, final ReadableInstant lastUsed) {
|
||||
this.user = user;
|
||||
this.algorithm = algorithm;
|
||||
|
||||
this.siteName = siteName;
|
||||
this.siteState = siteState;
|
||||
this.siteCounter = ifNotNullElse( siteCounter, user.getAlgorithm().mpw_default_counter() );
|
||||
this.resultType = ifNotNullElse( resultType, user.getAlgorithm().mpw_default_password_type() );
|
||||
this.algorithm = algorithm;
|
||||
this.siteCounter = ifNotNullElse( siteCounter, getAlgorithm().mpw_default_counter() );
|
||||
this.resultType = ifNotNullElse( resultType, getAlgorithm().mpw_default_password_type() );
|
||||
this.loginState = loginState;
|
||||
this.loginType = ifNotNullElse( loginType, getAlgorithm().mpw_default_login_type() );
|
||||
this.url = url;
|
||||
@ -116,15 +120,15 @@ public class MPFileSite extends MPSite {
|
||||
return siteState;
|
||||
}
|
||||
|
||||
public void setSitePassword(final MPResultType resultType, @Nullable final String result)
|
||||
public void setSitePassword(final MPResultType resultType, @Nullable final String password)
|
||||
throws MPKeyUnavailableException {
|
||||
this.resultType = resultType;
|
||||
|
||||
if (result == null)
|
||||
if (password == null)
|
||||
this.siteState = null;
|
||||
else
|
||||
this.siteState = user.getMasterKey().siteState(
|
||||
siteName, siteCounter, MPKeyPurpose.Authentication, null, resultType, result, algorithm );
|
||||
this.siteState = getState(
|
||||
MPKeyPurpose.Authentication, null, siteCounter, resultType, password );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -155,7 +159,6 @@ public class MPFileSite extends MPSite {
|
||||
@Override
|
||||
public void setLoginType(@Nullable final MPResultType loginType) {
|
||||
this.loginType = ifNotNullElse( loginType, getAlgorithm().mpw_default_login_type() );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -168,6 +171,11 @@ public class MPFileSite extends MPSite {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends MPQuestion> getQuestions() {
|
||||
return Collections.unmodifiableCollection( questions );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLoginState() {
|
||||
return loginState;
|
||||
@ -176,9 +184,7 @@ public class MPFileSite extends MPSite {
|
||||
public void setLoginName(@Nonnull final MPResultType loginType, @Nonnull final String loginName)
|
||||
throws MPKeyUnavailableException {
|
||||
this.loginType = loginType;
|
||||
this.loginState = user.getMasterKey().siteState(
|
||||
siteName, algorithm.mpw_default_counter(), MPKeyPurpose.Identification, null,
|
||||
this.loginType, loginName, algorithm );
|
||||
this.loginState = getState( MPKeyPurpose.Identification, null, null, this.loginType, loginName );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -39,7 +39,7 @@ public class MPFileUser extends MPUser<MPFileSite> implements Comparable<MPFileU
|
||||
private static final Logger logger = Logger.get( MPFileUser.class );
|
||||
|
||||
private final String fullName;
|
||||
private final Collection<MPFileSite> sites = Sets.newHashSet();
|
||||
private final Collection<MPFileSite> sites = new LinkedHashSet<>();
|
||||
|
||||
@Nullable
|
||||
private byte[] keyID;
|
||||
@ -136,7 +136,7 @@ public class MPFileUser extends MPUser<MPFileSite> implements Comparable<MPFileU
|
||||
lastUsed = new Instant();
|
||||
}
|
||||
|
||||
public Iterable<MPFileSite> getSites() {
|
||||
public Collection<MPFileSite> getSites() {
|
||||
return Collections.unmodifiableCollection( sites );
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
//==============================================================================
|
||||
// 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.model;
|
||||
|
||||
import com.lyndir.masterpassword.*;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
/**
|
||||
* @author lhunath, 2018-05-14
|
||||
*/
|
||||
public abstract class MPQuestion {
|
||||
|
||||
public abstract MPSite getSite();
|
||||
|
||||
public abstract String getKeyword();
|
||||
|
||||
public abstract MPResultType getType();
|
||||
|
||||
public String getAnswer(@Nullable final String state)
|
||||
throws MPKeyUnavailableException {
|
||||
|
||||
return getSite().getResult( MPKeyPurpose.Recovery, getKeyword(), null, getType(), state );
|
||||
}
|
||||
}
|
@ -18,10 +18,12 @@
|
||||
|
||||
package com.lyndir.masterpassword.model;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
||||
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.lyndir.masterpassword.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -54,21 +56,40 @@ public abstract class MPSite {
|
||||
public abstract void setAlgorithm(MPAlgorithm algorithm);
|
||||
|
||||
public String getResult(final MPKeyPurpose keyPurpose, @Nullable final String keyContext,
|
||||
@Nullable final String siteContent)
|
||||
@Nullable final String state)
|
||||
throws MPKeyUnavailableException {
|
||||
|
||||
return getResult( keyPurpose, keyContext, getSiteCounter(), getResultType(), state );
|
||||
}
|
||||
|
||||
protected String getResult(final MPKeyPurpose keyPurpose, @Nullable final String keyContext,
|
||||
@Nullable final UnsignedInteger siteCounter, final MPResultType type,
|
||||
@Nullable final String state)
|
||||
throws MPKeyUnavailableException {
|
||||
|
||||
return getUser().getMasterKey().siteResult(
|
||||
getSiteName(), getSiteCounter(), keyPurpose, keyContext, getResultType(), siteContent, getAlgorithm() );
|
||||
getSiteName(), ifNotNullElse( siteCounter, getAlgorithm().mpw_default_counter() ), keyPurpose, keyContext,
|
||||
type, state, getAlgorithm() );
|
||||
}
|
||||
|
||||
protected String getState(final MPKeyPurpose keyPurpose, @Nullable final String keyContext,
|
||||
@Nullable final UnsignedInteger siteCounter, final MPResultType type,
|
||||
@Nullable final String state)
|
||||
throws MPKeyUnavailableException {
|
||||
|
||||
return getUser().getMasterKey().siteState(
|
||||
getSiteName(), ifNotNullElse( siteCounter, getAlgorithm().mpw_default_counter() ), keyPurpose, keyContext,
|
||||
type, state, getAlgorithm() );
|
||||
}
|
||||
|
||||
public String getLogin(@Nullable final String loginContent)
|
||||
throws MPKeyUnavailableException {
|
||||
|
||||
return getUser().getMasterKey().siteResult(
|
||||
getSiteName(), getAlgorithm().mpw_default_counter(), MPKeyPurpose.Identification, null,
|
||||
getLoginType(), loginContent, getAlgorithm() );
|
||||
return getResult( MPKeyPurpose.Identification, null,null, getLoginType(), loginContent );
|
||||
}
|
||||
|
||||
public abstract Collection<? extends MPQuestion> getQuestions();
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return (this == obj) || ((obj instanceof MPSite) && Objects.equals( getSiteName(), ((MPSite) obj).getSiteName() ));
|
||||
|
@ -20,11 +20,13 @@ package com.lyndir.masterpassword.gui.model;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.ifNotNullElse;
|
||||
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.lyndir.masterpassword.MPAlgorithm;
|
||||
import com.lyndir.masterpassword.MPResultType;
|
||||
import com.lyndir.masterpassword.model.MPSite;
|
||||
import com.lyndir.masterpassword.model.MPUser;
|
||||
import com.lyndir.masterpassword.model.*;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
@ -95,6 +97,11 @@ public class IncognitoSite extends MPSite {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MPQuestion> getQuestions() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnsignedInteger getSiteCounter() {
|
||||
return siteCounter;
|
||||
|
@ -260,9 +260,7 @@ public abstract class PasswordFrame<U extends MPUser<S>, S extends MPSite> exten
|
||||
@Override
|
||||
public String call()
|
||||
throws Exception {
|
||||
return user.getMasterKey()
|
||||
.siteResult( site.getSiteName(), site.getSiteCounter(), MPKeyPurpose.Authentication, null, site.getResultType(),
|
||||
null, site.getAlgorithm() );
|
||||
return site.getResult( MPKeyPurpose.Authentication, null, null );
|
||||
}
|
||||
} );
|
||||
Futures.addCallback( passwordFuture, new FutureCallback<String>() {
|
||||
|
Loading…
Reference in New Issue
Block a user