Apply 'Lhunath' code inspection fixes and improvements.
This commit is contained in:
@@ -10,7 +10,7 @@ import java.nio.charset.Charset;
|
||||
/**
|
||||
* @author lhunath, 2016-10-29
|
||||
*/
|
||||
public class MPConstant {
|
||||
public final class MPConstant {
|
||||
|
||||
/* Environment */
|
||||
|
||||
@@ -58,17 +58,24 @@ public class MPConstant {
|
||||
/**
|
||||
* mpw: Input character encoding.
|
||||
*/
|
||||
public static final Charset mpw_charset = Charsets.UTF_8;
|
||||
public static final Charset mpw_charset = Charsets.UTF_8;
|
||||
/**
|
||||
* mpw: Platform-agnostic byte order.
|
||||
*/
|
||||
public static final ByteOrder mpw_byteOrder = ByteOrder.BIG_ENDIAN;
|
||||
public static final ByteOrder mpw_byteOrder = ByteOrder.BIG_ENDIAN;
|
||||
/**
|
||||
* mpw: Site digest.
|
||||
*/
|
||||
public static final MessageAuthenticationDigests mpw_digest = MessageAuthenticationDigests.HmacSHA256;
|
||||
public static final MessageAuthenticationDigests mpw_digest = MessageAuthenticationDigests.HmacSHA256;
|
||||
/**
|
||||
* mpw: Key ID hash.
|
||||
*/
|
||||
public static final MessageDigests mpw_hash = MessageDigests.SHA256;
|
||||
public static final MessageDigests mpw_hash = MessageDigests.SHA256;
|
||||
/**
|
||||
* mpw: validity for the time-based rolling counter.
|
||||
*/
|
||||
public static final int mpw_counter_timeout = 5 * 60 /* s */;
|
||||
|
||||
|
||||
public static final int MS_PER_S = 1000;
|
||||
}
|
||||
|
@@ -19,12 +19,12 @@ public class MPIdenticon {
|
||||
private static final Logger logger = Logger.get( MPIdenticon.class );
|
||||
|
||||
private static final Charset charset = Charsets.UTF_8;
|
||||
private static final Color[] colors = new Color[]{
|
||||
private static final Color[] colors = {
|
||||
Color.RED, Color.GREEN, Color.YELLOW, Color.BLUE, Color.MAGENTA, Color.CYAN, Color.MONO };
|
||||
private static final char[] leftArm = new char[]{ '╔', '╚', '╰', '═' };
|
||||
private static final char[] rightArm = new char[]{ '╗', '╝', '╯', '═' };
|
||||
private static final char[] body = new char[]{ '█', '░', '▒', '▓', '☺', '☻' };
|
||||
private static final char[] accessory = new char[]{
|
||||
private static final char[] leftArm = { '╔', '╚', '╰', '═' };
|
||||
private static final char[] rightArm = { '╗', '╝', '╯', '═' };
|
||||
private static final char[] body = { '█', '░', '▒', '▓', '☺', '☻' };
|
||||
private static final char[] accessory = {
|
||||
'◈', '◎', '◐', '◑', '◒', '◓', '☀', '☁', '☂', '☃', '☄', '★', '☆', '☎', '☏', '⎈', '⌂', '☘', '☢', '☣', '☕', '⌚', '⌛', '⏰', '⚡',
|
||||
'⛄', '⛅', '☔', '♔', '♕', '♖', '♗', '♘', '♙', '♚', '♛', '♜', '♝', '♞', '♟', '♨', '♩', '♪', '♫', '⚐', '⚑', '⚔', '⚖', '⚙', '⚠',
|
||||
'⌘', '⏎', '✄', '✆', '✈', '✉', '✌' };
|
||||
@@ -33,11 +33,12 @@ public class MPIdenticon {
|
||||
private final Color color;
|
||||
private final String text;
|
||||
|
||||
public MPIdenticon(String fullName, String masterPassword) {
|
||||
public MPIdenticon(final String fullName, final String masterPassword) {
|
||||
this( fullName, masterPassword.toCharArray() );
|
||||
}
|
||||
|
||||
public MPIdenticon(String fullName, char[] masterPassword) {
|
||||
@SuppressWarnings("MethodCanBeVariableArityMethod")
|
||||
public MPIdenticon(final String fullName, final char[] masterPassword) {
|
||||
this.fullName = fullName;
|
||||
|
||||
byte[] masterPasswordBytes = charset.encode( CharBuffer.wrap( masterPassword ) ).array();
|
||||
|
@@ -3,10 +3,10 @@ package com.lyndir.masterpassword;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
|
||||
/**
|
||||
@@ -17,12 +17,12 @@ import org.jetbrains.annotations.Contract;
|
||||
public enum MPSiteType {
|
||||
|
||||
GeneratedMaximum( "Max", "20 characters, contains symbols.", //
|
||||
ImmutableList.of( "x", "max", "maximum" ), //
|
||||
ImmutableList.of( "x", "max", "maximum" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "anoxxxxxxxxxxxxxxxxx" ), new MPTemplate( "axxxxxxxxxxxxxxxxxno" ) ), //
|
||||
MPSiteTypeClass.Generated, 0x0 ),
|
||||
|
||||
GeneratedLong( "Long", "Copy-friendly, 14 characters, contains symbols.", //
|
||||
ImmutableList.of( "l", "long" ), //
|
||||
ImmutableList.of( "l", "long" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "CvcvnoCvcvCvcv" ), new MPTemplate( "CvcvCvcvnoCvcv" ),
|
||||
new MPTemplate( "CvcvCvcvCvcvno" ), new MPTemplate( "CvccnoCvcvCvcv" ),
|
||||
new MPTemplate( "CvccCvcvnoCvcv" ), new MPTemplate( "CvccCvcvCvcvno" ),
|
||||
@@ -37,43 +37,43 @@ public enum MPSiteType {
|
||||
MPSiteTypeClass.Generated, 0x1 ),
|
||||
|
||||
GeneratedMedium( "Medium", "Copy-friendly, 8 characters, contains symbols.", //
|
||||
ImmutableList.of( "m", "med", "medium" ), //
|
||||
ImmutableList.of( "m", "med", "medium" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "CvcnoCvc" ), new MPTemplate( "CvcCvcno" ) ), //
|
||||
MPSiteTypeClass.Generated, 0x2 ),
|
||||
|
||||
GeneratedBasic( "Basic", "8 characters, no symbols.", //
|
||||
ImmutableList.of( "b", "basic" ), //
|
||||
ImmutableList.of( "b", "basic" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "aaanaaan" ), new MPTemplate( "aannaaan" ), new MPTemplate( "aaannaaa" ) ), //
|
||||
MPSiteTypeClass.Generated, 0x3 ),
|
||||
|
||||
GeneratedShort( "Short", "Copy-friendly, 4 characters, no symbols.", //
|
||||
ImmutableList.of( "s", "short" ), //
|
||||
ImmutableList.of( "s", "short" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "Cvcn" ) ), //
|
||||
MPSiteTypeClass.Generated, 0x4 ),
|
||||
|
||||
GeneratedPIN( "PIN", "4 numbers.", //
|
||||
ImmutableList.of( "i", "pin" ), //
|
||||
ImmutableList.of( "i", "pin" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "nnnn" ) ), //
|
||||
MPSiteTypeClass.Generated, 0x5 ),
|
||||
|
||||
GeneratedName( "Name", "9 letter name.", //
|
||||
ImmutableList.of( "n", "name" ), //
|
||||
ImmutableList.of( "n", "name" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "cvccvcvcv" ) ), //
|
||||
MPSiteTypeClass.Generated, 0xE ),
|
||||
|
||||
GeneratedPhrase( "Phrase", "20 character sentence.", //
|
||||
ImmutableList.of( "p", "phrase" ), //
|
||||
ImmutableList.of( "p", "phrase" ), // NON-NLS
|
||||
ImmutableList.of( new MPTemplate( "cvcc cvc cvccvcv cvc" ), new MPTemplate( "cvc cvccvcvcv cvcv" ),
|
||||
new MPTemplate( "cv cvccv cvc cvcvccv" ) ), //
|
||||
MPSiteTypeClass.Generated, 0xF ),
|
||||
|
||||
StoredPersonal( "Personal", "AES-encrypted, exportable.", //
|
||||
ImmutableList.of( "personal" ), //
|
||||
ImmutableList.of( "personal" ), // NON-NLS
|
||||
ImmutableList.<MPTemplate>of(), //
|
||||
MPSiteTypeClass.Stored, 0x0, MPSiteFeature.ExportContent ),
|
||||
|
||||
StoredDevicePrivate( "Device", "AES-encrypted, not exported.", //
|
||||
ImmutableList.of( "device" ), //
|
||||
ImmutableList.of( "device" ), // NON-NLS
|
||||
ImmutableList.<MPTemplate>of(), //
|
||||
MPSiteTypeClass.Stored, 0x1, MPSiteFeature.DevicePrivate );
|
||||
|
||||
@@ -129,7 +129,7 @@ public enum MPSiteType {
|
||||
|
||||
public int getType() {
|
||||
int mask = typeIndex | typeClass.getMask();
|
||||
for (MPSiteFeature typeFeature : typeFeatures)
|
||||
for (final MPSiteFeature typeFeature : typeFeatures)
|
||||
mask |= typeFeature.getMask();
|
||||
|
||||
return mask;
|
||||
@@ -143,7 +143,7 @@ public enum MPSiteType {
|
||||
public static MPSiteType forOption(final String option) {
|
||||
|
||||
for (final MPSiteType type : values())
|
||||
if (type.getOptions().contains( option.toLowerCase() ))
|
||||
if (type.getOptions().contains( option.toLowerCase( Locale.ROOT ) ))
|
||||
return type;
|
||||
|
||||
throw logger.bug( "No type for option: %s", option );
|
||||
@@ -154,7 +154,7 @@ public enum MPSiteType {
|
||||
*
|
||||
* @return The type registered with the given name.
|
||||
*/
|
||||
@Contract("!null -> !null, null -> null")
|
||||
@Contract("!null -> !null")
|
||||
public static MPSiteType forName(@Nullable final String name) {
|
||||
|
||||
if (name == null)
|
||||
@@ -189,7 +189,7 @@ public enum MPSiteType {
|
||||
*/
|
||||
public static MPSiteType forType(final int type) {
|
||||
|
||||
for (MPSiteType siteType : values())
|
||||
for (final MPSiteType siteType : values())
|
||||
if (siteType.getType() == type)
|
||||
return siteType;
|
||||
|
||||
@@ -205,7 +205,7 @@ public enum MPSiteType {
|
||||
|
||||
int typeMask = mask & ~0xF;
|
||||
ImmutableList.Builder<MPSiteType> types = ImmutableList.builder();
|
||||
for (MPSiteType siteType : values())
|
||||
for (final MPSiteType siteType : values())
|
||||
if (((siteType.getType() & ~0xF) & typeMask) != 0)
|
||||
types.add( siteType );
|
||||
|
||||
|
@@ -3,8 +3,10 @@ package com.lyndir.masterpassword;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
|
||||
/**
|
||||
@@ -12,11 +14,11 @@ import org.jetbrains.annotations.Contract;
|
||||
*/
|
||||
public enum MPSiteVariant {
|
||||
Password( "Generate a key for authentication.", "Doesn't currently use a context.", //
|
||||
ImmutableList.of( "p", "password" ), "com.lyndir.masterpassword" ),
|
||||
ImmutableList.of( "p", "password" ), "com.lyndir.masterpassword" ), // NON-NLS
|
||||
Login( "Generate a name for identification.", "Doesn't currently use a context.", //
|
||||
ImmutableList.of( "l", "login" ), "com.lyndir.masterpassword.login" ),
|
||||
ImmutableList.of( "l", "login" ), "com.lyndir.masterpassword.login" ), // NON-NLS
|
||||
Answer( "Generate an answer to a security question.", "Empty for a universal site answer or\nthe most significant word(s) of the question.", //
|
||||
ImmutableList.of( "a", "answer" ), "com.lyndir.masterpassword.answer" );
|
||||
ImmutableList.of( "a", "answer" ), "com.lyndir.masterpassword.answer" ); // NON-NLS
|
||||
|
||||
static final Logger logger = Logger.get( MPSiteType.class );
|
||||
|
||||
@@ -25,7 +27,7 @@ public enum MPSiteVariant {
|
||||
private final List<String> options;
|
||||
private final String scope;
|
||||
|
||||
MPSiteVariant(final String description, final String contextDescription, final List<String> options, final String scope) {
|
||||
MPSiteVariant(final String description, final String contextDescription, final List<String> options, @NonNls final String scope) {
|
||||
this.contextDescription = contextDescription;
|
||||
|
||||
this.options = options;
|
||||
@@ -57,7 +59,7 @@ public enum MPSiteVariant {
|
||||
public static MPSiteVariant forOption(final String option) {
|
||||
|
||||
for (final MPSiteVariant variant : values())
|
||||
if (variant.getOptions().contains( option.toLowerCase() ))
|
||||
if (variant.getOptions().contains( option.toLowerCase( Locale.ROOT ) ))
|
||||
return variant;
|
||||
|
||||
throw logger.bug( "No variant for option: %s", option );
|
||||
@@ -67,7 +69,7 @@ public enum MPSiteVariant {
|
||||
*
|
||||
* @return The variant registered with the given name.
|
||||
*/
|
||||
@Contract("!null -> !null, null -> null")
|
||||
@Contract("!null -> !null")
|
||||
public static MPSiteVariant forName(@Nullable final String name) {
|
||||
|
||||
if (name == null)
|
||||
|
@@ -4,7 +4,9 @@ import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.lyndir.lhunath.opal.system.util.MetaObject;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
|
||||
/**
|
||||
@@ -12,12 +14,14 @@ import java.util.List;
|
||||
*
|
||||
* @author lhunath
|
||||
*/
|
||||
public class MPTemplate extends MetaObject {
|
||||
public class MPTemplate extends MetaObject implements Serializable {
|
||||
|
||||
private final String templateString;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String templateString;
|
||||
private final List<MPTemplateCharacterClass> template;
|
||||
|
||||
MPTemplate(final String templateString) {
|
||||
MPTemplate(@NonNls final String templateString) {
|
||||
|
||||
ImmutableList.Builder<MPTemplateCharacterClass> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < templateString.length(); ++i)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package com.lyndir.masterpassword;
|
||||
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
|
||||
/**
|
||||
@@ -27,7 +28,7 @@ public enum MPTemplateCharacterClass {
|
||||
private final char identifier;
|
||||
private final char[] characters;
|
||||
|
||||
MPTemplateCharacterClass(final char identifier, final String characters) {
|
||||
MPTemplateCharacterClass(final char identifier, @NonNls final String characters) {
|
||||
|
||||
this.identifier = identifier;
|
||||
this.characters = characters.toCharArray();
|
||||
@@ -44,7 +45,7 @@ public enum MPTemplateCharacterClass {
|
||||
}
|
||||
|
||||
public static MPTemplateCharacterClass forIdentifier(final char identifier) {
|
||||
for (MPTemplateCharacterClass characterClass : values())
|
||||
for (final MPTemplateCharacterClass characterClass : values())
|
||||
if (characterClass.getIdentifier() == identifier)
|
||||
return characterClass;
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package com.lyndir.masterpassword;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.lyndir.lhunath.opal.system.*;
|
||||
@@ -7,7 +9,6 @@ import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import java.util.Arrays;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
/**
|
||||
@@ -26,13 +27,15 @@ public abstract class MasterKey {
|
||||
@Nullable
|
||||
private byte[] masterKey;
|
||||
|
||||
@SuppressWarnings("MethodCanBeVariableArityMethod")
|
||||
public static MasterKey create(final String fullName, final char[] masterPassword) {
|
||||
|
||||
return create( Version.CURRENT, fullName, masterPassword );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static MasterKey create(Version version, final String fullName, final char[] masterPassword) {
|
||||
@SuppressWarnings("MethodCanBeVariableArityMethod")
|
||||
public static MasterKey create(final Version version, final String fullName, final char[] masterPassword) {
|
||||
|
||||
switch (version) {
|
||||
case V0:
|
||||
@@ -45,7 +48,7 @@ public abstract class MasterKey {
|
||||
return new MasterKeyV3( fullName ).revalidate( masterPassword );
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException( "Unsupported version: " + version );
|
||||
throw new UnsupportedOperationException( strf( "Unsupported version: %s", version ) );
|
||||
}
|
||||
|
||||
public static boolean isAllowNativeByDefault() {
|
||||
@@ -65,18 +68,19 @@ public abstract class MasterKey {
|
||||
allowNativeByDefault = allowNative;
|
||||
}
|
||||
|
||||
protected MasterKey(@NotNull final String fullName) {
|
||||
protected MasterKey(@Nonnull final String fullName) {
|
||||
|
||||
this.fullName = fullName;
|
||||
logger.trc( "fullName: %s", fullName );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract byte[] deriveKey(final char[] masterPassword);
|
||||
@SuppressWarnings("MethodCanBeVariableArityMethod")
|
||||
protected abstract byte[] deriveKey(char[] masterPassword);
|
||||
|
||||
public abstract Version getAlgorithmVersion();
|
||||
|
||||
@NotNull
|
||||
@Nonnull
|
||||
public String getFullName() {
|
||||
|
||||
return fullName;
|
||||
@@ -103,8 +107,8 @@ public abstract class MasterKey {
|
||||
return idForBytes( getKey() );
|
||||
}
|
||||
|
||||
public abstract String encode(@Nonnull final String siteName, final MPSiteType siteType, @Nonnull final UnsignedInteger siteCounter,
|
||||
final MPSiteVariant siteVariant, @Nullable final String siteContext);
|
||||
public abstract String encode(@Nonnull String siteName, MPSiteType siteType, @Nonnull UnsignedInteger siteCounter,
|
||||
MPSiteVariant siteVariant, @Nullable String siteContext);
|
||||
|
||||
public boolean isValid() {
|
||||
return masterKey != null;
|
||||
@@ -118,6 +122,7 @@ public abstract class MasterKey {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodCanBeVariableArityMethod")
|
||||
public MasterKey revalidate(final char[] masterPassword) {
|
||||
invalidate();
|
||||
|
||||
@@ -127,19 +132,19 @@ public abstract class MasterKey {
|
||||
masterKey = deriveKey( masterPassword );
|
||||
|
||||
if (masterKey == null)
|
||||
logger.dbg( "masterKey calculation failed after %.2fs.", (System.currentTimeMillis() - start) / 1000D );
|
||||
logger.dbg( "masterKey calculation failed after %.2fs.", (double)(System.currentTimeMillis() - start) / MPConstant.MS_PER_S );
|
||||
else
|
||||
logger.trc( "masterKey ID: %s (derived in %.2fs)", CodeUtils.encodeHex( idForBytes( masterKey ) ),
|
||||
(System.currentTimeMillis() - start) / 1000D );
|
||||
(double)(System.currentTimeMillis() - start) / MPConstant.MS_PER_S );
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract byte[] bytesForInt(final int number);
|
||||
protected abstract byte[] bytesForInt(int number);
|
||||
|
||||
protected abstract byte[] bytesForInt(@Nonnull final UnsignedInteger number);
|
||||
protected abstract byte[] bytesForInt(@Nonnull UnsignedInteger number);
|
||||
|
||||
protected abstract byte[] idForBytes(final byte[] bytes);
|
||||
protected abstract byte[] idForBytes(byte[] bytes);
|
||||
|
||||
public enum Version {
|
||||
/**
|
||||
@@ -190,7 +195,7 @@ public abstract class MasterKey {
|
||||
return "2.2";
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException( "Unsupported version: " + this );
|
||||
throw new UnsupportedOperationException( strf( "Unsupported version: %s", this ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -58,6 +58,7 @@ public class MasterKeyV0 extends MasterKey {
|
||||
return scrypt( masterKeySalt, mpBytes );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected byte[] scrypt(final byte[] masterKeySalt, final byte[] mpBytes) {
|
||||
try {
|
||||
if (isAllowNative())
|
||||
@@ -65,7 +66,7 @@ public class MasterKeyV0 extends MasterKey {
|
||||
else
|
||||
return SCrypt.scryptJ( mpBytes, masterKeySalt, MPConstant.scrypt_N, MPConstant.scrypt_r, MPConstant.scrypt_p, MPConstant.mpw_dkLen );
|
||||
}
|
||||
catch (GeneralSecurityException e) {
|
||||
catch (final GeneralSecurityException e) {
|
||||
logger.bug( e );
|
||||
return null;
|
||||
}
|
||||
@@ -86,18 +87,18 @@ public class MasterKeyV0 extends MasterKey {
|
||||
logger.trc( "siteType: %d (%s)", siteType.ordinal(), siteType );
|
||||
|
||||
if (siteCounter.longValue() == 0)
|
||||
siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (300 * 1000)) * 300 );
|
||||
siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (MPConstant.mpw_counter_timeout * 1000)) * MPConstant.mpw_counter_timeout );
|
||||
|
||||
String siteScope = siteVariant.getScope();
|
||||
byte[] siteNameBytes = siteName.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteNameLengthBytes = bytesForInt( siteName.length() );
|
||||
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
||||
byte[] siteContextBytes = siteContext == null || siteContext.isEmpty()? null: siteContext.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
||||
logger.trc( "site scope: %s, context: %s", siteScope, siteContextBytes == null? "<empty>": siteContext );
|
||||
byte[] siteContextBytes = ((siteContext == null) || siteContext.isEmpty())? null: siteContext.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteContextLengthBytes = bytesForInt( (siteContextBytes == null)? 0: siteContextBytes.length );
|
||||
logger.trc( "site scope: %s, context: %s", siteScope, (siteContextBytes == null)? "<empty>": siteContext );
|
||||
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
||||
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
||||
siteContextBytes == null? "(null)": siteContext );
|
||||
(siteContextBytes == null)? "(null)": siteContext );
|
||||
|
||||
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MPConstant.mpw_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
||||
if (siteContextBytes != null)
|
||||
@@ -108,7 +109,7 @@ public class MasterKeyV0 extends MasterKey {
|
||||
int[] sitePasswordSeed = new int[sitePasswordSeedBytes.length];
|
||||
for (int i = 0; i < sitePasswordSeedBytes.length; ++i) {
|
||||
ByteBuffer buf = ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( ByteOrder.BIG_ENDIAN );
|
||||
Arrays.fill( buf.array(), sitePasswordSeedBytes[i] > 0? (byte) 0x00: (byte) 0xFF );
|
||||
Arrays.fill( buf.array(), (byte) ((sitePasswordSeedBytes[i] > 0)? 0x00: 0xFF) );
|
||||
buf.position( 2 );
|
||||
buf.put( sitePasswordSeedBytes[i] ).rewind();
|
||||
sitePasswordSeed[i] = buf.getInt() & 0xFFFF;
|
||||
|
@@ -43,18 +43,18 @@ public class MasterKeyV1 extends MasterKeyV0 {
|
||||
logger.trc( "siteType: %d (%s)", siteType.ordinal(), siteType );
|
||||
|
||||
if (siteCounter.longValue() == 0)
|
||||
siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (300 * 1000)) * 300 );
|
||||
siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (MPConstant.mpw_counter_timeout * 1000)) * MPConstant.mpw_counter_timeout );
|
||||
|
||||
String siteScope = siteVariant.getScope();
|
||||
byte[] siteNameBytes = siteName.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteNameLengthBytes = bytesForInt( siteName.length() );
|
||||
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
||||
byte[] siteContextBytes = siteContext == null || siteContext.isEmpty()? null: siteContext.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
||||
logger.trc( "site scope: %s, context: %s", siteScope, siteContextBytes == null? "<empty>": siteContext );
|
||||
byte[] siteContextBytes = ((siteContext == null) || siteContext.isEmpty())? null: siteContext.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteContextLengthBytes = bytesForInt( (siteContextBytes == null)? 0: siteContextBytes.length );
|
||||
logger.trc( "site scope: %s, context: %s", siteScope, (siteContextBytes == null)? "<empty>": siteContext );
|
||||
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
||||
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
||||
siteContextBytes == null? "(null)": siteContext );
|
||||
(siteContextBytes == null)? "(null)": siteContext );
|
||||
|
||||
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MPConstant.mpw_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
||||
if (siteContextBytes != null)
|
||||
|
@@ -42,18 +42,18 @@ public class MasterKeyV2 extends MasterKeyV1 {
|
||||
logger.trc( "siteType: %d (%s)", siteType.ordinal(), siteType );
|
||||
|
||||
if (siteCounter.longValue() == 0)
|
||||
siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (300 * 1000)) * 300 );
|
||||
siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (MPConstant.mpw_counter_timeout * 1000)) * MPConstant.mpw_counter_timeout );
|
||||
|
||||
String siteScope = siteVariant.getScope();
|
||||
byte[] siteNameBytes = siteName.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteNameLengthBytes = bytesForInt( siteNameBytes.length );
|
||||
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
||||
byte[] siteContextBytes = siteContext == null || siteContext.isEmpty()? null: siteContext.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
||||
logger.trc( "site scope: %s, context: %s", siteScope, siteContextBytes == null? "<empty>": siteContext );
|
||||
byte[] siteContextBytes = ((siteContext == null) || siteContext.isEmpty())? null: siteContext.getBytes( MPConstant.mpw_charset );
|
||||
byte[] siteContextLengthBytes = bytesForInt( (siteContextBytes == null)? 0: siteContextBytes.length );
|
||||
logger.trc( "site scope: %s, context: %s", siteScope, (siteContextBytes == null)? "<empty>": siteContext );
|
||||
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
||||
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
||||
siteContextBytes == null? "(null)": siteContext );
|
||||
(siteContextBytes == null)? "(null)": siteContext );
|
||||
|
||||
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MPConstant.mpw_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
||||
if (siteContextBytes != null)
|
||||
|
@@ -6,7 +6,7 @@ plugins {
|
||||
description = 'Master Password Site Model'
|
||||
|
||||
dependencies {
|
||||
compile project(':masterpassword:algorithm')
|
||||
compile project(':masterpassword-algorithm')
|
||||
|
||||
compile group: 'joda-time', name: 'joda-time', version:'2.4'
|
||||
compileOnly group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
|
||||
|
@@ -128,7 +128,7 @@ public class MPSite {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return this == obj || obj instanceof MPSite && Objects.equals( siteName, ((MPSite) obj).siteName );
|
||||
return (this == obj) || ((obj instanceof MPSite) && Objects.equals( siteName, ((MPSite) obj).siteName ));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -26,7 +26,7 @@ public class MPSiteMarshaller {
|
||||
public static MPSiteMarshaller marshallSafe(final MPUser user) {
|
||||
MPSiteMarshaller marshaller = new MPSiteMarshaller();
|
||||
marshaller.marshallHeaderForSafeContent( user );
|
||||
for (MPSite site : user.getSites())
|
||||
for (final MPSite site : user.getSites())
|
||||
marshaller.marshallSite( site );
|
||||
|
||||
return marshaller;
|
||||
@@ -35,7 +35,7 @@ public class MPSiteMarshaller {
|
||||
public static MPSiteMarshaller marshallVisible(final MPUser user, final MasterKey masterKey) {
|
||||
MPSiteMarshaller marshaller = new MPSiteMarshaller();
|
||||
marshaller.marshallHeaderForVisibleContentWithKey( user, masterKey );
|
||||
for (MPSite site : user.getSites())
|
||||
for (final MPSite site : user.getSites())
|
||||
marshaller.marshallSite( site );
|
||||
|
||||
return marshaller;
|
||||
@@ -77,7 +77,7 @@ public class MPSiteMarshaller {
|
||||
return header.toString();
|
||||
}
|
||||
|
||||
public String marshallSite(MPSite site) {
|
||||
public String marshallSite(final MPSite site) {
|
||||
String exportLine = strf( "%s %8d %8s %25s\t%25s\t%s", //
|
||||
rfc3339.print( site.getLastUsed() ), // lastUsed
|
||||
site.getUses(), // uses
|
||||
@@ -126,6 +126,6 @@ public class MPSiteMarshaller {
|
||||
return description;
|
||||
}
|
||||
|
||||
public abstract String contentForSite(final MPSite site, final MasterKey masterKey);
|
||||
public abstract String contentForSite(MPSite site, MasterKey masterKey);
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ public class MPSiteResult {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return this == obj || obj instanceof MPSiteResult && Objects.equals( site, ((MPSiteResult) obj).site );
|
||||
return (this == obj) || ((obj instanceof MPSiteResult) && Objects.equals( site, ((MPSiteResult) obj).site ));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -2,6 +2,7 @@ package com.lyndir.masterpassword.model;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.CharStreams;
|
||||
@@ -31,26 +32,28 @@ public class MPSiteUnmarshaller {
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private static final Logger logger = Logger.get( MPSite.class );
|
||||
private static final DateTimeFormatter rfc3339 = ISODateTimeFormat.dateTimeNoMillis();
|
||||
private static final Pattern[] unmarshallFormats = new Pattern[]{
|
||||
private static final Pattern[] unmarshallFormats = {
|
||||
Pattern.compile( "^([^ ]+) +(\\d+) +(\\d+)(:\\d+)? +([^\t]+)\t(.*)" ),
|
||||
Pattern.compile( "^([^ ]+) +(\\d+) +(\\d+)(:\\d+)?(:\\d+)? +([^\t]*)\t *([^\t]+)\t(.*)" ) };
|
||||
private static final Pattern headerFormat = Pattern.compile( "^#\\s*([^:]+): (.*)" );
|
||||
|
||||
private final int importFormat;
|
||||
@SuppressWarnings({ "FieldCanBeLocal", "unused" })
|
||||
private final int mpVersion;
|
||||
@SuppressWarnings({ "FieldCanBeLocal", "unused" })
|
||||
private final boolean clearContent;
|
||||
private final MPUser user;
|
||||
|
||||
@Nonnull
|
||||
public static MPSiteUnmarshaller unmarshall(@Nonnull File file)
|
||||
public static MPSiteUnmarshaller unmarshall(@Nonnull final File file)
|
||||
throws IOException {
|
||||
try (Reader reader = new FileReader( file )) {
|
||||
try (Reader reader = new InputStreamReader( new FileInputStream( file ), Charsets.UTF_8 )) {
|
||||
return unmarshall( CharStreams.readLines( reader ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static MPSiteUnmarshaller unmarshall(@Nonnull List<String> lines) {
|
||||
public static MPSiteUnmarshaller unmarshall(@Nonnull final List<String> lines) {
|
||||
byte[] keyID = null;
|
||||
String fullName = null;
|
||||
int mpVersion = 0, importFormat = 0, avatar = 0;
|
||||
@@ -59,7 +62,7 @@ public class MPSiteUnmarshaller {
|
||||
MPSiteUnmarshaller marshaller = null;
|
||||
final ImmutableList.Builder<MPSite> sites = ImmutableList.builder();
|
||||
|
||||
for (String line : lines)
|
||||
for (final String line : lines)
|
||||
// Header delimitor.
|
||||
if (line.startsWith( "##" ))
|
||||
if (!headerStarted)
|
||||
@@ -71,7 +74,7 @@ public class MPSiteUnmarshaller {
|
||||
|
||||
// Comment.
|
||||
else if (line.startsWith( "#" )) {
|
||||
if (headerStarted && marshaller == null) {
|
||||
if (headerStarted && (marshaller == null)) {
|
||||
// In header.
|
||||
Matcher headerMatcher = headerFormat.matcher( line );
|
||||
if (headerMatcher.matches()) {
|
||||
@@ -87,7 +90,7 @@ public class MPSiteUnmarshaller {
|
||||
else if ("Avatar".equalsIgnoreCase( name ))
|
||||
avatar = ConversionUtils.toIntegerNN( value );
|
||||
else if ("Passwords".equalsIgnoreCase( name ))
|
||||
clearContent = value.equalsIgnoreCase( "visible" );
|
||||
clearContent = "visible".equalsIgnoreCase( value );
|
||||
else if ("Default Type".equalsIgnoreCase( name ))
|
||||
defaultType = MPSiteType.forType( ConversionUtils.toIntegerNN( value ) );
|
||||
}
|
||||
@@ -116,7 +119,7 @@ public class MPSiteUnmarshaller {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MPSite unmarshallSite(@Nonnull String siteLine) {
|
||||
public MPSite unmarshallSite(@Nonnull final String siteLine) {
|
||||
Matcher siteMatcher = unmarshallFormats[importFormat].matcher( siteLine );
|
||||
if (!siteMatcher.matches())
|
||||
return null;
|
||||
|
@@ -39,16 +39,16 @@ public class MPUser implements Comparable<MPUser> {
|
||||
public MPUser(final String fullName, @Nullable final byte[] keyID, final MasterKey.Version algorithmVersion, final int avatar,
|
||||
final MPSiteType defaultType, final ReadableInstant lastUsed) {
|
||||
this.fullName = fullName;
|
||||
this.keyID = keyID;
|
||||
this.keyID = (keyID == null)? null: keyID.clone();
|
||||
this.algorithmVersion = algorithmVersion;
|
||||
this.avatar = avatar;
|
||||
this.defaultType = defaultType;
|
||||
this.lastUsed = lastUsed;
|
||||
}
|
||||
|
||||
public Collection<MPSiteResult> findSitesByName(String query) {
|
||||
public Collection<MPSiteResult> findSitesByName(final String query) {
|
||||
ImmutableList.Builder<MPSiteResult> results = ImmutableList.builder();
|
||||
for (MPSite site : getSites())
|
||||
for (final MPSite site : getSites())
|
||||
if (site.getSiteName().startsWith( query ))
|
||||
results.add( new MPSiteResult( site ) );
|
||||
|
||||
@@ -87,10 +87,11 @@ public class MPUser implements Comparable<MPUser> {
|
||||
* @throws IncorrectMasterPasswordException If authentication fails due to the given master password not matching the user's keyID.
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("MethodCanBeVariableArityMethod")
|
||||
public MasterKey authenticate(final char[] masterPassword)
|
||||
throws IncorrectMasterPasswordException {
|
||||
MasterKey masterKey = MasterKey.create( algorithmVersion, getFullName(), masterPassword );
|
||||
if (keyID == null || keyID.length == 0)
|
||||
if ((keyID == null) || (keyID.length == 0))
|
||||
keyID = masterKey.getKeyID();
|
||||
else if (!Arrays.equals( masterKey.getKeyID(), keyID ))
|
||||
throw new IncorrectMasterPasswordException( this );
|
||||
@@ -119,7 +120,7 @@ public class MPUser implements Comparable<MPUser> {
|
||||
}
|
||||
|
||||
public void updateLastUsed() {
|
||||
this.lastUsed = new Instant();
|
||||
lastUsed = new Instant();
|
||||
}
|
||||
|
||||
public Iterable<MPSite> getSites() {
|
||||
@@ -128,7 +129,7 @@ public class MPUser implements Comparable<MPUser> {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return this == obj || obj instanceof MPUser && Objects.equals( fullName, ((MPUser) obj).fullName );
|
||||
return (this == obj) || ((obj instanceof MPUser) && Objects.equals( fullName, ((MPUser) obj).fullName ));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -59,7 +59,7 @@ public class MPUserFileManager extends MPUserManager {
|
||||
try {
|
||||
return MPSiteUnmarshaller.unmarshall( Preconditions.checkNotNull( file ) ).getUser();
|
||||
}
|
||||
catch (IOException e) {
|
||||
catch (final IOException e) {
|
||||
logger.err( e, "Couldn't read user from: %s", file );
|
||||
return null;
|
||||
}
|
||||
@@ -99,16 +99,17 @@ public class MPUserFileManager extends MPUserManager {
|
||||
@Override
|
||||
public Writer openStream()
|
||||
throws IOException {
|
||||
return new FileWriter( new File( userFilesDirectory, user.getFullName() + ".mpsites" ) );
|
||||
File mpsitesFile = new File( userFilesDirectory, user.getFullName() + ".mpsites" );
|
||||
return new OutputStreamWriter( new FileOutputStream( mpsitesFile ), Charsets.UTF_8 );
|
||||
}
|
||||
}.write( MPSiteMarshaller.marshallSafe( user ).getExport() );
|
||||
}
|
||||
catch (IOException e) {
|
||||
catch (final IOException e) {
|
||||
logger.err( e, "Unable to save sites for user: %s", user );
|
||||
}
|
||||
|
||||
// Remove deleted users.
|
||||
for (File userFile : listUserFiles( userFilesDirectory ))
|
||||
for (final File userFile : listUserFiles( userFilesDirectory ))
|
||||
if (getUserNamed( userFile.getName().replaceFirst( "\\.mpsites$", "" ) ) == null)
|
||||
if (!userFile.delete())
|
||||
logger.err( "Couldn't delete file: %s", userFile );
|
||||
|
@@ -17,7 +17,7 @@ public abstract class MPUserManager {
|
||||
}
|
||||
|
||||
protected MPUserManager(final Iterable<MPUser> users) {
|
||||
for (MPUser user : users)
|
||||
for (final MPUser user : users)
|
||||
usersByName.put( user.getFullName(), user );
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public abstract class MPUserManager {
|
||||
return FluentIterable.from( usersByName.values() ).toSortedSet( Ordering.natural() );
|
||||
}
|
||||
|
||||
public MPUser getUserNamed(String fullName) {
|
||||
public MPUser getUserNamed(final String fullName) {
|
||||
return usersByName.get( fullName );
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@ plugins {
|
||||
description = 'Master Password Test Suite'
|
||||
|
||||
dependencies {
|
||||
compile project(':masterpassword:algorithm')
|
||||
compile project(':masterpassword-algorithm')
|
||||
|
||||
testCompile group: 'org.testng', name: 'testng', version:'6.8.5'
|
||||
testCompile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.2'
|
||||
|
@@ -20,29 +20,30 @@ import org.xml.sax.ext.DefaultHandler2;
|
||||
/**
|
||||
* @author lhunath, 2015-12-22
|
||||
*/
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
public class MPTestSuite implements Callable<Boolean> {
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private static final Logger logger = Logger.get( MPTestSuite.class );
|
||||
private static final String DEFAULT_RESOURCE_NAME = "mpw_tests.xml";
|
||||
|
||||
private MPTests tests;
|
||||
private Listener listener;
|
||||
private final MPTests tests;
|
||||
private Listener listener;
|
||||
|
||||
public MPTestSuite()
|
||||
throws UnavailableException {
|
||||
this( DEFAULT_RESOURCE_NAME );
|
||||
}
|
||||
|
||||
public MPTestSuite(String resourceName)
|
||||
public MPTestSuite(final String resourceName)
|
||||
throws UnavailableException {
|
||||
try {
|
||||
tests = new MPTests();
|
||||
tests.cases = Lists.newLinkedList();
|
||||
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
|
||||
parser.parse( Thread.currentThread().getContextClassLoader().getResourceAsStream( resourceName ), new DefaultHandler2() {
|
||||
private Deque<String> currentTags = Lists.newLinkedList();
|
||||
private Deque<StringBuilder> currentTexts = Lists.newLinkedList();
|
||||
private final Deque<String> currentTags = Lists.newLinkedList();
|
||||
private final Deque<StringBuilder> currentTexts = Lists.newLinkedList();
|
||||
private MPTests.Case currentCase;
|
||||
|
||||
@Override
|
||||
@@ -103,7 +104,7 @@ public class MPTestSuite implements Callable<Boolean> {
|
||||
throw new UnavailableException( e );
|
||||
}
|
||||
|
||||
for (MPTests.Case testCase : tests.getCases())
|
||||
for (final MPTests.Case testCase : tests.getCases())
|
||||
testCase.initializeParentHierarchy( tests );
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ public class MPTestSuite implements Callable<Boolean> {
|
||||
return tests;
|
||||
}
|
||||
|
||||
public boolean forEach(String testName, NNFunctionNN<MPTests.Case, Boolean> testFunction) {
|
||||
public boolean forEach(final String testName, final NNFunctionNN<MPTests.Case, Boolean> testFunction) {
|
||||
List<MPTests.Case> cases = tests.getCases();
|
||||
for (int c = 0; c < cases.size(); c++) {
|
||||
MPTests.Case testCase = cases.get( c );
|
||||
@@ -164,6 +165,8 @@ public class MPTestSuite implements Callable<Boolean> {
|
||||
|
||||
public static class UnavailableException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UnavailableException(final Throwable cause) {
|
||||
super( cause );
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package com.lyndir.masterpassword;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
@@ -28,20 +29,20 @@ public class MPTests {
|
||||
return checkNotNull( cases );
|
||||
}
|
||||
|
||||
public Case getCase(String identifier) {
|
||||
for (Case testCase : getCases())
|
||||
public Case getCase(final String identifier) {
|
||||
for (final Case testCase : getCases())
|
||||
if (identifier.equals( testCase.getIdentifier() ))
|
||||
return testCase;
|
||||
|
||||
throw new IllegalArgumentException( "No case for identifier: " + identifier );
|
||||
throw new IllegalArgumentException( strf( "No case for identifier: %s", identifier ) );
|
||||
}
|
||||
|
||||
public Case getDefaultCase() {
|
||||
try {
|
||||
return getCase( ID_DEFAULT );
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new IllegalStateException( "Missing default case in test suite. Add a case with id: " + ID_DEFAULT, e );
|
||||
catch (final IllegalArgumentException e) {
|
||||
throw new IllegalStateException( strf( "Missing default case in test suite. Add a case with id: %d", ID_DEFAULT ), e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ public class MPTests {
|
||||
|
||||
private transient Case parentCase;
|
||||
|
||||
public void initializeParentHierarchy(MPTests tests) {
|
||||
public void initializeParentHierarchy(final MPTests tests) {
|
||||
|
||||
if (parent != null) {
|
||||
parentCase = tests.getCase( parent );
|
||||
@@ -129,14 +130,14 @@ public class MPTests {
|
||||
@Nonnull
|
||||
@Override
|
||||
public String get() {
|
||||
return parentCase == null? "": checkNotNull( parentCase.siteContext );
|
||||
return (parentCase == null)? "": checkNotNull( parentCase.siteContext );
|
||||
}
|
||||
} );
|
||||
result = ifNotNullElse( result, new NNSupplier<String>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public String get() {
|
||||
return parentCase == null? "": checkNotNull( parentCase.result );
|
||||
return (parentCase == null)? "": checkNotNull( parentCase.result );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import com.lyndir.lhunath.opal.system.util.NNFunctionNN;
|
||||
import javax.annotation.Nonnull;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -15,6 +16,7 @@ public class MasterKeyTest {
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private static final Logger logger = Logger.get( MasterKeyTest.class );
|
||||
|
||||
@NonNls
|
||||
private MPTestSuite testSuite;
|
||||
|
||||
@BeforeMethod
|
||||
@@ -86,7 +88,7 @@ public class MasterKeyTest {
|
||||
|
||||
fail( "[testInvalidate] Master key should have been invalidated, but was still usable." );
|
||||
}
|
||||
catch (IllegalStateException ignored) {
|
||||
catch (final IllegalStateException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user