Skip to content

Commit

Permalink
Cleaned up code and fixed test cases
Browse files Browse the repository at this point in the history
* Use combo box instead of radio buttons for case options
  • Loading branch information
droidmonkey committed May 24, 2019
1 parent fc4ae70 commit 3a83e82
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 135 deletions.
21 changes: 8 additions & 13 deletions src/core/PassphraseGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,9 @@ void PassphraseGenerator::setWordCount(int wordCount)
}
}

void PassphraseGenerator::setWordCase(int wordCase)
void PassphraseGenerator::setWordCase(PassphraseWordCase wordCase)
{
if (wordCase >= PassphraseGenerator::MIN_VALUE && wordCase <= PassphraseGenerator::MAX_VALUE ) {
m_wordCase = wordCase;
} else {
// safe default (lowercase) if something goes wrong
m_wordCase = 0;
}
m_wordCase = wordCase;
}

void PassphraseGenerator::setWordList(const QString& path)
Expand Down Expand Up @@ -111,16 +106,16 @@ QString PassphraseGenerator::generatePassphrase() const
int wordIndex = randomGen()->randomUInt(static_cast<quint32>(m_wordlist.length()));
tmpWord = m_wordlist.at(wordIndex);

//convert case
// convert case
switch (m_wordCase) {
case PassphraseGenerator::UPPERCASE :
case UPPERCASE:
tmpWord = tmpWord.toUpper();
break;
case PassphraseGenerator::TITLECASE :
tmpWord = tmpWord.replace(0,1,tmpWord.left(1).toUpper());
case TITLECASE:
tmpWord = tmpWord.replace(0, 1, tmpWord.left(1).toUpper());
break;
case PassphraseGenerator::LOWERCASE :
default :
case LOWERCASE:
default:
tmpWord = tmpWord.toLower();
break;
}
Expand Down
16 changes: 10 additions & 6 deletions src/core/PassphraseGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,31 @@ class PassphraseGenerator
PassphraseGenerator();
Q_DISABLE_COPY(PassphraseGenerator)

enum PassphraseWordCase
{
LOWERCASE,
UPPERCASE,
TITLECASE
};

double calculateEntropy(const QString& passphrase);
void setWordCount(int wordCount);
void setWordList(const QString& path);
void setWordCase(int wordCase);
void setWordCase(PassphraseWordCase wordCase);
void setDefaultWordList();
void setWordSeparator(const QString& separator);
bool isValid() const;

QString generatePassphrase() const;

enum PassphraseWordCase { LOWERCASE = 0, UPPERCASE = 1, TITLECASE = 2, MIN_VALUE = LOWERCASE, MAX_VALUE = TITLECASE };
Q_DECLARE_FLAGS(PassphraseWordCases, PassphraseWordCase)

static constexpr int DefaultWordCount = 7;
static constexpr int DefaultWordCase = PassphraseGenerator::LOWERCASE;
static constexpr PassphraseWordCase DefaultWordCase = LOWERCASE;
static const char* DefaultSeparator;
static const char* DefaultWordList;

private:
int m_wordCount;
int m_wordCase;
PassphraseWordCase m_wordCase;
QString m_separator;
QVector<QString> m_wordlist;
};
Expand Down
21 changes: 9 additions & 12 deletions src/gui/PasswordGeneratorWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent)
connect(m_ui->comboBoxWordList, SIGNAL(currentIndexChanged(int)), SLOT(updateGenerator()));
connect(m_ui->optionButtons, SIGNAL(buttonClicked(int)), SLOT(updateGenerator()));
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(updateGenerator()));
connect(m_ui->wordCaseButtonGroup, SIGNAL(buttonClicked(int)), SLOT(updateGenerator()));
connect(m_ui->wordCaseComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateGenerator()));

// set font size of password quality and entropy labels dynamically to 80% of
// the default font size, but make it no smaller than 8pt
Expand All @@ -75,13 +75,10 @@ PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent)
// set default separator to Space
m_ui->editWordSeparator->setText(PassphraseGenerator::DefaultSeparator);

// set the ids of the radiobuttons
m_ui->wordCaseButtonGroup->setId(m_ui->wordCaseLowerRadioButton, PassphraseGenerator::LOWERCASE);
m_ui->wordCaseButtonGroup->setId(m_ui->wordCaseUpperRadioButton, PassphraseGenerator::UPPERCASE);
m_ui->wordCaseButtonGroup->setId(m_ui->wordCaseTitleRadioButton, PassphraseGenerator::TITLECASE);

// set word case to lowercase (default)
m_ui->wordCaseButtonGroup->button(PassphraseGenerator::LOWERCASE)->isChecked();
// add passphrase generator case options
m_ui->wordCaseComboBox->addItem(tr("lower case"), PassphraseGenerator::LOWERCASE);
m_ui->wordCaseComboBox->addItem(tr("UPPER CASE"), PassphraseGenerator::UPPERCASE);
m_ui->wordCaseComboBox->addItem(tr("Title Case"), PassphraseGenerator::TITLECASE);

QDir path(filePath()->wordlistPath(""));
QStringList files = path.entryList(QDir::Files);
Expand Down Expand Up @@ -148,8 +145,7 @@ void PasswordGeneratorWidget::loadSettings()
config()->get("generator/WordSeparator", PassphraseGenerator::DefaultSeparator).toString());
m_ui->comboBoxWordList->setCurrentText(
config()->get("generator/WordList", PassphraseGenerator::DefaultWordList).toString());
m_ui->wordCaseButtonGroup->button(
config()->get("generator/WordCase", PassphraseGenerator::DefaultWordCase).toInt())->isChecked();
m_ui->wordCaseComboBox->setCurrentIndex(config()->get("generator/WordCase", 0).toInt());

// Password or diceware?
m_ui->tabWidget->setCurrentIndex(config()->get("generator/Type", 0).toInt());
Expand Down Expand Up @@ -185,7 +181,7 @@ void PasswordGeneratorWidget::saveSettings()
config()->set("generator/WordCount", m_ui->spinBoxWordCount->value());
config()->set("generator/WordSeparator", m_ui->editWordSeparator->text());
config()->set("generator/WordList", m_ui->comboBoxWordList->currentText());
config()->set("generator/WordCase", m_ui->wordCaseButtonGroup->checkedId());
config()->set("generator/WordCase", m_ui->wordCaseComboBox->currentIndex());

// Password or diceware?
config()->set("generator/Type", m_ui->tabWidget->currentIndex());
Expand Down Expand Up @@ -568,7 +564,8 @@ void PasswordGeneratorWidget::updateGenerator()
m_updatingSpinBox = false;
}

m_dicewareGenerator->setWordCase(m_ui->wordCaseButtonGroup->checkedId());
m_dicewareGenerator->setWordCase(
static_cast<PassphraseGenerator::PassphraseWordCase>(m_ui->wordCaseComboBox->currentData().toInt()));

m_ui->spinBoxWordCount->setMinimum(minWordCount);
m_ui->sliderWordCount->setMinimum(minWordCount);
Expand Down
151 changes: 63 additions & 88 deletions src/gui/PasswordGeneratorWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -927,16 +927,56 @@ QProgressBar::chunk {
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="labelWordCount">
<item row="3" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="wordCaseLabel">
<property name="text">
<string>Word Co&amp;unt:</string>
<string>Word Case:</string>
</property>
<property name="buddy">
<cstring>spinBoxLength</cstring>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxWordList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="labelWordSeparator">
<property name="text">
<string>Word Separator:</string>
</property>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="labelWordList">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wordlist:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="sizeConstraint">
Expand Down Expand Up @@ -982,28 +1022,15 @@ QProgressBar::chunk {
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxWordList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
<item row="1" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="labelWordCount">
<property name="text">
<string>Word Co&amp;unt:</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
<property name="buddy">
<cstring>spinBoxLength</cstring>
</property>
</spacer>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="editWordSeparator">
Expand All @@ -1012,70 +1039,26 @@ QProgressBar::chunk {
</property>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="labelWordList">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wordlist:</string>
</property>
</widget>
</item>
<item row="3" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="wordCaseLabel">
<property name="text">
<string>Word Case:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayoutWordCase">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QRadioButton" name="wordCaseLowerRadioButton">
<property name="text">
<string>lower case (default)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">wordCaseButtonGroup</string>
</attribute>
</widget>
<widget class="QComboBox" name="wordCaseComboBox"/>
</item>
<item>
<widget class="QRadioButton" name="wordCaseUpperRadioButton">
<property name="text">
<string>UPPER CASE</string>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<attribute name="buttonGroup">
<string notr="true">wordCaseButtonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="wordCaseTitleRadioButton">
<property name="text">
<string>Title Case</string>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
<attribute name="buttonGroup">
<string notr="true">wordCaseButtonGroup</string>
</attribute>
</widget>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="labelWordSeparator">
<property name="text">
<string>Word Separator:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
Expand Down Expand Up @@ -1179,21 +1162,13 @@ QProgressBar::chunk {
<tabstop>sliderWordCount</tabstop>
<tabstop>spinBoxWordCount</tabstop>
<tabstop>editWordSeparator</tabstop>
<tabstop>wordCaseLowerRadioButton</tabstop>
<tabstop>wordCaseUpperRadioButton</tabstop>
<tabstop>wordCaseTitleRadioButton</tabstop>
<tabstop>buttonGenerate</tabstop>
<tabstop>buttonCopy</tabstop>
<tabstop>buttonApply</tabstop>
</tabstops>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="wordCaseButtonGroup">
<property name="exclusive">
<bool>true</bool>
</property>
</buttongroup>
<buttongroup name="optionButtons">
<property name="exclusive">
<bool>false</bool>
Expand Down
3 changes: 3 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ add_unit_test(NAME testmerge SOURCES TestMerge.cpp
add_unit_test(NAME testpasswordgenerator SOURCES TestPasswordGenerator.cpp
LIBS ${TEST_LIBRARIES})

add_unit_test(NAME testpassphrasegenerator SOURCES TestPassphraseGenerator.cpp
LIBS ${TEST_LIBRARIES})

add_unit_test(NAME testtotp SOURCES TestTotp.cpp
LIBS ${TEST_LIBRARIES})

Expand Down
26 changes: 11 additions & 15 deletions tests/TestPassphraseGenerator.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2019 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -32,35 +32,31 @@ void TestPassphraseGenerator::initTestCase()
void TestPassphraseGenerator::testWordCase()
{
PassphraseGenerator generator;
generator.setDefaultWordList();

generator.setWordCount(1);
generator.setWordCase(-3); // invalid - should default to lowercase
QVERIFY(generator.isValid());
QString password = generator.generatePassword();
QVERIFY(password.isLower());
QString passphrase;

generator.setWordCount(1);
generator.setWordCase(99); // invalid - should default to lowercase
QVERIFY(generator.isValid());
QString password = generator.generatePassword();
QVERIFY(password.isLower());
passphrase = generator.generatePassphrase();
QVERIFY(passphrase == passphrase.toLower());

generator.setWordCount(1);
generator.setWordCase(PassphraseGenerator::LOWERCASE);
QVERIFY(generator.isValid());
QString password = generator.generatePassword();
QVERIFY(password.isLower());
passphrase = generator.generatePassphrase();
QVERIFY(passphrase == passphrase.toLower());

generator.setWordCount(1);
generator.setWordCase(PassphraseGenerator::UPPERCASE);
QVERIFY(generator.isValid());
QString password = generator.generatePassword();
QVERIFY(password.isUpper());
passphrase = generator.generatePassphrase();
QVERIFY(passphrase == passphrase.toUpper());

generator.setWordCount(1);
generator.setWordCase(PassphraseGenerator::TITLECASE);
QVERIFY(generator.isValid());
QString password = generator.generatePassword();
passphrase = generator.generatePassphrase();
QRegularExpression regex("^[A-Z][a-z]*+$");
QVERIFY(regex.match(password).hasMatch());
QVERIFY(regex.match(passphrase).hasMatch());
}
Loading

0 comments on commit 3a83e82

Please sign in to comment.