Add -i/--include option to "generate" CLI command. (#7112)
This commit is contained in:
@@ -53,6 +53,12 @@ const QCommandLineOption Generate::ExcludeCharsOption = QCommandLineOption(QStri
|
||||
QObject::tr("Exclude character set"),
|
||||
QObject::tr("chars"));
|
||||
|
||||
const QCommandLineOption Generate::CustomCharacterSetOption =
|
||||
QCommandLineOption(QStringList() << "c"
|
||||
<< "custom",
|
||||
QObject::tr("Use custom character set"),
|
||||
QObject::tr("chars"));
|
||||
|
||||
const QCommandLineOption Generate::ExcludeSimilarCharsOption =
|
||||
QCommandLineOption(QStringList() << "exclude-similar", QObject::tr("Exclude similar looking characters"));
|
||||
|
||||
@@ -71,6 +77,7 @@ Generate::Generate()
|
||||
options.append(Generate::ExcludeCharsOption);
|
||||
options.append(Generate::ExcludeSimilarCharsOption);
|
||||
options.append(Generate::IncludeEveryGroupOption);
|
||||
options.append(Generate::CustomCharacterSetOption);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,9 +127,15 @@ QSharedPointer<PasswordGenerator> Generate::createGenerator(QSharedPointer<QComm
|
||||
|
||||
// The default charset will be used if no explicit class
|
||||
// option was set.
|
||||
passwordGenerator->setCharClasses(classes);
|
||||
passwordGenerator->setFlags(flags);
|
||||
passwordGenerator->setExcludedChars(parser->value(Generate::ExcludeCharsOption));
|
||||
if (flags != 0x0) {
|
||||
passwordGenerator->setFlags(flags);
|
||||
}
|
||||
QString customCharacterSet = parser->value(Generate::CustomCharacterSetOption);
|
||||
if (classes != 0x0 || !customCharacterSet.isNull()) {
|
||||
passwordGenerator->setCharClasses(classes);
|
||||
}
|
||||
passwordGenerator->setCustomCharacterSet(customCharacterSet);
|
||||
passwordGenerator->setExcludedCharacterSet(parser->value(Generate::ExcludeCharsOption));
|
||||
|
||||
if (!passwordGenerator->isValid()) {
|
||||
err << QObject::tr("Invalid password generator after applying all options") << endl;
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
static const QCommandLineOption ExcludeCharsOption;
|
||||
static const QCommandLineOption ExcludeSimilarCharsOption;
|
||||
static const QCommandLineOption IncludeEveryGroupOption;
|
||||
static const QCommandLineOption CustomCharacterSetOption;
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_GENERATE_H
|
||||
|
||||
@@ -20,51 +20,43 @@
|
||||
|
||||
#include "crypto/Random.h"
|
||||
|
||||
const char* PasswordGenerator::DefaultAdditionalChars = "";
|
||||
const int PasswordGenerator::DefaultLength = 32;
|
||||
const char* PasswordGenerator::DefaultCustomCharacterSet = "";
|
||||
const char* PasswordGenerator::DefaultExcludedChars = "";
|
||||
|
||||
PasswordGenerator::PasswordGenerator()
|
||||
: m_length(0)
|
||||
, m_classes(nullptr)
|
||||
, m_flags(nullptr)
|
||||
, m_additional(PasswordGenerator::DefaultAdditionalChars)
|
||||
: m_length(PasswordGenerator::DefaultLength)
|
||||
, m_classes(PasswordGenerator::CharClass::DefaultCharset)
|
||||
, m_flags(PasswordGenerator::GeneratorFlag::DefaultFlags)
|
||||
, m_custom(PasswordGenerator::DefaultCustomCharacterSet)
|
||||
, m_excluded(PasswordGenerator::DefaultExcludedChars)
|
||||
{
|
||||
}
|
||||
|
||||
void PasswordGenerator::setLength(int length)
|
||||
{
|
||||
if (length <= 0) {
|
||||
m_length = DefaultLength;
|
||||
return;
|
||||
}
|
||||
m_length = length;
|
||||
}
|
||||
|
||||
void PasswordGenerator::setCharClasses(const CharClasses& classes)
|
||||
void PasswordGenerator::setCharClasses(const PasswordGenerator::CharClasses& classes)
|
||||
{
|
||||
if (classes == 0) {
|
||||
m_classes = DefaultCharset;
|
||||
return;
|
||||
}
|
||||
m_classes = classes;
|
||||
}
|
||||
|
||||
void PasswordGenerator::setCustomCharacterSet(const QString& customCharacterSet)
|
||||
{
|
||||
m_custom = customCharacterSet;
|
||||
}
|
||||
void PasswordGenerator::setExcludedCharacterSet(const QString& excludedCharacterSet)
|
||||
{
|
||||
m_excluded = excludedCharacterSet;
|
||||
}
|
||||
|
||||
void PasswordGenerator::setFlags(const GeneratorFlags& flags)
|
||||
{
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
void PasswordGenerator::setAdditionalChars(const QString& chars)
|
||||
{
|
||||
m_additional = chars;
|
||||
}
|
||||
|
||||
void PasswordGenerator::setExcludedChars(const QString& chars)
|
||||
{
|
||||
m_excluded = chars;
|
||||
}
|
||||
|
||||
QString PasswordGenerator::generatePassword() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
@@ -114,9 +106,9 @@ QString PasswordGenerator::generatePassword() const
|
||||
|
||||
bool PasswordGenerator::isValid() const
|
||||
{
|
||||
if (m_classes == 0 && m_additional.isEmpty()) {
|
||||
if (m_classes == CharClass::NoClass && m_custom.isEmpty()) {
|
||||
return false;
|
||||
} else if (m_length == 0) {
|
||||
} else if (m_length <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -266,10 +258,10 @@ QVector<PasswordGroup> PasswordGenerator::passwordGroups() const
|
||||
|
||||
passwordGroups.append(group);
|
||||
}
|
||||
if (!m_additional.isEmpty()) {
|
||||
if (!m_custom.isEmpty()) {
|
||||
PasswordGroup group;
|
||||
|
||||
for (auto ch : m_additional) {
|
||||
for (auto ch : m_custom) {
|
||||
group.append(ch);
|
||||
}
|
||||
|
||||
@@ -302,38 +294,43 @@ QVector<PasswordGroup> PasswordGenerator::passwordGroups() const
|
||||
|
||||
int PasswordGenerator::numCharClasses() const
|
||||
{
|
||||
int numClasses = 0;
|
||||
|
||||
if (m_classes & LowerLetters) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & UpperLetters) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & Numbers) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & Braces) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & Punctuation) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & Quotes) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & Dashes) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & Math) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & Logograms) {
|
||||
numClasses++;
|
||||
}
|
||||
if (m_classes & EASCII) {
|
||||
numClasses++;
|
||||
}
|
||||
|
||||
return numClasses;
|
||||
// Actually compute the non empty password groups
|
||||
auto non_empty_groups = passwordGroups();
|
||||
return non_empty_groups.size();
|
||||
}
|
||||
|
||||
int PasswordGenerator::getMinLength() const
|
||||
{
|
||||
if ((m_flags & CharFromEveryGroup)) {
|
||||
return numCharClasses();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
void PasswordGenerator::reset()
|
||||
{
|
||||
m_classes = CharClass::DefaultCharset;
|
||||
m_flags = GeneratorFlag::DefaultFlags;
|
||||
m_custom = DefaultCustomCharacterSet;
|
||||
m_excluded = DefaultExcludedChars;
|
||||
m_length = DefaultLength;
|
||||
}
|
||||
int PasswordGenerator::getLength() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
const PasswordGenerator::GeneratorFlags& PasswordGenerator::getFlags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
const PasswordGenerator::CharClasses& PasswordGenerator::getActiveClasses() const
|
||||
{
|
||||
return m_classes;
|
||||
}
|
||||
const QString& PasswordGenerator::getCustomCharacterSet() const
|
||||
{
|
||||
return m_custom;
|
||||
}
|
||||
const QString& PasswordGenerator::getExcludedCharacterSet() const
|
||||
{
|
||||
return m_excluded;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifndef KEEPASSX_PASSWORDGENERATOR_H
|
||||
#define KEEPASSX_PASSWORDGENERATOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
typedef QVector<QChar> PasswordGroup;
|
||||
@@ -28,6 +29,7 @@ class PasswordGenerator
|
||||
public:
|
||||
enum CharClass
|
||||
{
|
||||
NoClass = 0,
|
||||
LowerLetters = (1 << 0),
|
||||
UpperLetters = (1 << 1),
|
||||
Numbers = (1 << 2),
|
||||
@@ -41,10 +43,11 @@ public:
|
||||
EASCII = (1 << 9),
|
||||
DefaultCharset = LowerLetters | UpperLetters | Numbers
|
||||
};
|
||||
Q_DECLARE_FLAGS(CharClasses, CharClass)
|
||||
Q_DECLARE_FLAGS(CharClasses, CharClass);
|
||||
|
||||
enum GeneratorFlag
|
||||
{
|
||||
NoFlags = 0,
|
||||
ExcludeLookAlike = (1 << 0),
|
||||
CharFromEveryGroup = (1 << 1),
|
||||
AdvancedMode = (1 << 2),
|
||||
@@ -56,17 +59,25 @@ public:
|
||||
PasswordGenerator();
|
||||
|
||||
void setLength(int length);
|
||||
void setCharClasses(const CharClasses& classes);
|
||||
void setFlags(const GeneratorFlags& flags);
|
||||
void setAdditionalChars(const QString& chars);
|
||||
void setExcludedChars(const QString& chars);
|
||||
void setCharClasses(const CharClasses& classes);
|
||||
void setCustomCharacterSet(const QString& customCharacterSet);
|
||||
void setExcludedCharacterSet(const QString& excludedCharacterSet);
|
||||
void reset();
|
||||
|
||||
bool isValid() const;
|
||||
int getMinLength() const;
|
||||
|
||||
int getLength() const;
|
||||
const GeneratorFlags& getFlags() const;
|
||||
const CharClasses& getActiveClasses() const;
|
||||
const QString& getCustomCharacterSet() const;
|
||||
const QString& getExcludedCharacterSet() const;
|
||||
|
||||
QString generatePassword() const;
|
||||
|
||||
static const int DefaultLength = 32;
|
||||
static const char* DefaultAdditionalChars;
|
||||
static const int DefaultLength;
|
||||
static const char* DefaultCustomCharacterSet;
|
||||
static const char* DefaultExcludedChars;
|
||||
|
||||
private:
|
||||
@@ -76,10 +87,8 @@ private:
|
||||
int m_length;
|
||||
CharClasses m_classes;
|
||||
GeneratorFlags m_flags;
|
||||
QString m_additional;
|
||||
QString m_custom;
|
||||
QString m_excluded;
|
||||
|
||||
Q_DISABLE_COPY(PasswordGenerator)
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(PasswordGenerator::CharClasses)
|
||||
|
||||
@@ -576,51 +576,15 @@ void PasswordGeneratorWidget::updateGenerator()
|
||||
auto classes = charClasses();
|
||||
auto flags = generatorFlags();
|
||||
|
||||
int length = 0;
|
||||
if (flags.testFlag(PasswordGenerator::CharFromEveryGroup)) {
|
||||
if (classes.testFlag(PasswordGenerator::LowerLetters)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::UpperLetters)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::Numbers)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::Braces)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::Punctuation)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::Quotes)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::Dashes)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::Math)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::Logograms)) {
|
||||
++length;
|
||||
}
|
||||
if (classes.testFlag(PasswordGenerator::EASCII)) {
|
||||
++length;
|
||||
}
|
||||
}
|
||||
|
||||
length = qMax(length, m_ui->spinBoxLength->value());
|
||||
m_passwordGenerator->setLength(length);
|
||||
m_passwordGenerator->setCharClasses(classes);
|
||||
m_passwordGenerator->setFlags(flags);
|
||||
m_passwordGenerator->setLength(m_ui->spinBoxLength->value());
|
||||
if (m_ui->buttonAdvancedMode->isChecked()) {
|
||||
m_passwordGenerator->setAdditionalChars(m_ui->editAdditionalChars->text());
|
||||
m_passwordGenerator->setExcludedChars(m_ui->editExcludedChars->text());
|
||||
m_passwordGenerator->setCharClasses(classes);
|
||||
m_passwordGenerator->setCustomCharacterSet(m_ui->editAdditionalChars->text());
|
||||
m_passwordGenerator->setCustomCharacterSet(m_ui->editExcludedChars->text());
|
||||
} else {
|
||||
m_passwordGenerator->setAdditionalChars("");
|
||||
m_passwordGenerator->setExcludedChars("");
|
||||
m_passwordGenerator->setCharClasses(classes);
|
||||
}
|
||||
m_passwordGenerator->setFlags(flags);
|
||||
|
||||
if (m_passwordGenerator->isValid()) {
|
||||
m_ui->buttonGenerate->setEnabled(true);
|
||||
|
||||
Reference in New Issue
Block a user