Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow users to use their own keyboard layouts and dictionaries #124

Conversation

yasuyuki-baba
Copy link
Member

I found #106
This pull request is a very nice improvement. I am impressed.

So I tried to give more freedom to customize the dictionary and keyboard layout.
I have achieved it by using the builder pattern and trying to specify resources in the code.
See src/test/java/com/nulabinc/zxcvbn/ZxcvbnBuilderTest.java for the example of the code to customize.

boolean found = false;
int foundDirection = -1;
int foundDirection;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The initial value of foundDirection doesn't have to be -1. It is always initialized with curDirection. 👍

return dictionaries;
}

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POSIX rules require a newline at the end of the file. Please add a newline.

image

try {
this.context = new ZxcvbnBuilder().buildContext();
} catch (IOException e) {
throw new IllegalStateException(e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is already Wrapped with IllegalStateException in buildContext as follows.
Is it necessary to CATCH here as well?

Context buildContext() throws IOException {
    try {
        // ...
        return new Context(dictionaryMap, keyboardMap);
    } catch (IOException e) {
        throw new IllegalStateException(e);
    }
}


Context buildContext() throws IOException {
try {
if (this.dictionaryMap.isEmpty() && this.keyboardMap.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the default dictionary and keyboard is added only when both are EMPTY.
How about checking each the dictionary and keyboard?

Example:

if (this.dictionaryMap.isEmpty()) {
    for (Dictionary dictionary : StandardDictionaries.loadAllDictionaries()) {
        this.dictionaryMap.put(dictionary.getName(), dictionary);
    }
}

if (this.keyboardMap.isEmpty()) {
    for (Keyboard keyboard : StandardKeyboards.loadAllKeyboards()) {
        this.keyboardMap.put(keyboard.getName(), keyboard);
    }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vvatanabe I designed it that way because I thought it would be difficult to tell when either the dictionary or the keyboard was not set, whether the user had not set it intentionally or had forgotten to set it.
However, let me consider it a bit further to see if there is a way to make it more clearly recognizable to users.


public class RegexGuess extends BaseGuess {

private static final Logger logger = Logger.getLogger(RegexGuess.class.getName());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete unused logger.

}

@Override

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete newline.

import java.util.Arrays;
import java.util.List;

public class AlignedAdjacentAdjacentGraphBuilder extends Keyboard.AdjacentGraphBuilder {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file and class name has been wrong for some time.

AlignedAdjacentAdjacentGraphBuilder -> AlignedAdjacentGraphBuilder

It's hard to review when there are more extra differences, so I can fix this with another issue.

}
return freqLists;
public Map<String, Integer> getRankedDictionary() {
return rankedDictionary;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POSIX rules require a newline at the end of the file. Please add a newline.
image

Map<Pattern, Integer[]> testMatches = new HashMap<>();
testMatches.put(Pattern.Dictionary, new Integer[]{0, 6});
//testMatches.put(Pattern.Dictionary, new Integer[]{0, 6});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out? Did you forget?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vvatanabe It looks like the value put in the commented-out line is overwritten by the next line.

            testMatches.put(Pattern.Dictionary, new Integer[]{7, 15});

So I commented out that line.

import com.nulabinc.zxcvbn.matchers.ReverseDictionaryMatcher;
import com.nulabinc.zxcvbn.matchers.SequenceMatcher;
import com.nulabinc.zxcvbn.matchers.SpatialMatcher;
import org.junit.*;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this package require a full import of junit?

import com.nulabinc.zxcvbn.matchers.Match;
import com.nulabinc.zxcvbn.matchers.MatchFactory;
import org.junit.Test;
import org.junit.*;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this package require a full import of junit?

@vvatanabe
Copy link
Member

@yasuyuki-baba These API designs are great. Thanks!
I have added some questions. Please check it out.

@vvatanabe
Copy link
Member

@lumarino just a notice

This approach allows custom dictionaries and keyboard settings to be defined entirely in code. By abstracting resources with InputStream, files other than classpaths (over HTTP, other directories in server) can also be used.

HOW TO USE:
src/test/java/com/nulabinc/zxcvbn/ZxcvbnBuilderTest.java
https://github.com/nulab/zxcvbn4j/pull/124/files#diff-ec06d7c12a656368307d2bc5811e2873fcd60a98b03ef01b4b70ddf74fdad82a

@yasuyuki-baba
Copy link
Member Author

@vvatanabe Thanks for reviewing my code!
There are still two areas where I have not reached a conclusion, but other than those, I have pushed changes based on your suggestions.

This means that if you want to use the standard dictionary and keyboard with ZxcvbnBuilder, you need to do something like ZxcvbnBuilder#testBuild2().
@yasuyuki-baba
Copy link
Member Author

yasuyuki-baba commented Apr 10, 2022

@vvatanabe I've made the following changes to make it explicit what dictionary and keyboard will be used. What do you think?

  • Only "new Zxcvbn();" loads the standard dictionary and keyboard.
  • This means that if you want to use the standard dictionary and keyboard with ZxcvbnBuilder, you need to do something like ZxcvbnBuilder#testBuild2().

@vvatanabe
Copy link
Member

@yasuyuki-baba

  • Only "new Zxcvbn();" loads the standard dictionary and keyboard.
  • This means that if you want to use the standard dictionary and keyboard with ZxcvbnBuilder, you need to do something like ZxcvbnBuilder#testBuild2().

The above changes look good! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants