Merge branch 'more-password-stuff'
This commit is contained in:
commit
6a142d9edb
@ -31,19 +31,15 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
PasswordCheck::PasswordCheck()
|
PasswordCheck::PasswordCheck()
|
||||||
: m_message()
|
: m_weight( 0 )
|
||||||
|
, m_message()
|
||||||
, m_accept( []( const QString& ) { return true; } )
|
, m_accept( []( const QString& ) { return true; } )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PasswordCheck::PasswordCheck( const QString& m, AcceptFunc a )
|
PasswordCheck::PasswordCheck( MessageFunc m, AcceptFunc a, Weight weight )
|
||||||
: m_message( [m]() { return m; } )
|
: m_weight( weight )
|
||||||
, m_accept( a )
|
, m_message( m )
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PasswordCheck::PasswordCheck( MessageFunc m, AcceptFunc a )
|
|
||||||
: m_message( m )
|
|
||||||
, m_accept( a )
|
, m_accept( a )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -59,7 +55,8 @@ DEFINE_CHECK_FUNC( minLength )
|
|||||||
{
|
{
|
||||||
cDebug() << Logger::SubEntry << "minLength set to" << minLength;
|
cDebug() << Logger::SubEntry << "minLength set to" << minLength;
|
||||||
checks.push_back( PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is too short" ); },
|
checks.push_back( PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is too short" ); },
|
||||||
[minLength]( const QString& s ) { return s.length() >= minLength; } ) );
|
[minLength]( const QString& s ) { return s.length() >= minLength; },
|
||||||
|
PasswordCheck::Weight( 10 ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +71,8 @@ DEFINE_CHECK_FUNC( maxLength )
|
|||||||
{
|
{
|
||||||
cDebug() << Logger::SubEntry << "maxLength set to" << maxLength;
|
cDebug() << Logger::SubEntry << "maxLength set to" << maxLength;
|
||||||
checks.push_back( PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is too long" ); },
|
checks.push_back( PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is too long" ); },
|
||||||
[maxLength]( const QString& s ) { return s.length() <= maxLength; } ) );
|
[maxLength]( const QString& s ) { return s.length() <= maxLength; },
|
||||||
|
PasswordCheck::Weight( 10 ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +361,8 @@ DEFINE_CHECK_FUNC( libpwquality )
|
|||||||
cDebug() << "Password strength" << r << "too low";
|
cDebug() << "Password strength" << r << "too low";
|
||||||
}
|
}
|
||||||
return r >= settings->arbitrary_minimum_strength;
|
return r >= settings->arbitrary_minimum_strength;
|
||||||
} ) );
|
},
|
||||||
|
PasswordCheck::Weight( 100 ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,11 +38,18 @@ public:
|
|||||||
using AcceptFunc = std::function< bool( const QString& ) >;
|
using AcceptFunc = std::function< bool( const QString& ) >;
|
||||||
using MessageFunc = std::function< QString() >;
|
using MessageFunc = std::function< QString() >;
|
||||||
|
|
||||||
/** Generate a @p message if @p filter returns true */
|
using Weight = size_t;
|
||||||
PasswordCheck( MessageFunc message, AcceptFunc filter );
|
|
||||||
/** Yields @p message if @p filter returns true */
|
/** @brief Generate a @p message if @p filter returns true
|
||||||
PasswordCheck( const QString& message, AcceptFunc filter );
|
*
|
||||||
/** Null check, always returns empty */
|
* When @p filter returns true on the proposed password, the
|
||||||
|
* password is accepted (by this check). If false, then the
|
||||||
|
* @p message will be shown to the user.
|
||||||
|
*
|
||||||
|
* @p weight is used to order the checks (low-weight goes first).
|
||||||
|
*/
|
||||||
|
PasswordCheck( MessageFunc message, AcceptFunc filter, Weight weight = 1000 );
|
||||||
|
/** @brief Null check, always accepts, no message */
|
||||||
PasswordCheck();
|
PasswordCheck();
|
||||||
|
|
||||||
/** Applies this check to the given password string @p s
|
/** Applies this check to the given password string @p s
|
||||||
@ -52,7 +59,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
QString filter( const QString& s ) const { return m_accept( s ) ? QString() : m_message(); }
|
QString filter( const QString& s ) const { return m_accept( s ) ? QString() : m_message(); }
|
||||||
|
|
||||||
|
Weight weight() const { return m_weight; }
|
||||||
|
bool operator<( const PasswordCheck& other ) const { return weight() < other.weight(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Weight m_weight;
|
||||||
MessageFunc m_message;
|
MessageFunc m_message;
|
||||||
AcceptFunc m_accept;
|
AcceptFunc m_accept;
|
||||||
};
|
};
|
||||||
|
@ -144,6 +144,11 @@ UsersPage::retranslate()
|
|||||||
"use this computer, you can create multiple "
|
"use this computer, you can create multiple "
|
||||||
"accounts after installation.</small>" ) );
|
"accounts after installation.</small>" ) );
|
||||||
}
|
}
|
||||||
|
// Re-do password checks (with output messages) as well.
|
||||||
|
// .. the password-checking methods get their values from the text boxes,
|
||||||
|
// not from their parameters.
|
||||||
|
onPasswordTextChanged( QString() );
|
||||||
|
onRootPasswordTextChanged( QString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -222,6 +227,8 @@ void
|
|||||||
UsersPage::onActivate()
|
UsersPage::onActivate()
|
||||||
{
|
{
|
||||||
ui->textBoxFullName->setFocus();
|
ui->textBoxFullName->setFocus();
|
||||||
|
onPasswordTextChanged( QString() );
|
||||||
|
onRootPasswordTextChanged( QString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -407,14 +414,7 @@ UsersPage::validateHostnameText( const QString& textRef )
|
|||||||
bool
|
bool
|
||||||
UsersPage::checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLabel* badge, QLabel* message )
|
UsersPage::checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLabel* badge, QLabel* message )
|
||||||
{
|
{
|
||||||
if ( pw1.isEmpty() && pw2.isEmpty() )
|
if ( pw1 != pw2 )
|
||||||
{
|
|
||||||
// Not exactly labelOk() because we also don't want a checkmark OK
|
|
||||||
badge->clear();
|
|
||||||
message->clear();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if ( pw1 != pw2 )
|
|
||||||
{
|
{
|
||||||
labelError( badge, message, tr( "Your passwords do not match!" ) );
|
labelError( badge, message, tr( "Your passwords do not match!" ) );
|
||||||
return false;
|
return false;
|
||||||
@ -424,6 +424,12 @@ UsersPage::checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLab
|
|||||||
bool failureIsFatal = ui->checkBoxValidatePassword->isChecked();
|
bool failureIsFatal = ui->checkBoxValidatePassword->isChecked();
|
||||||
bool failureFound = false;
|
bool failureFound = false;
|
||||||
|
|
||||||
|
if ( m_passwordChecksChanged )
|
||||||
|
{
|
||||||
|
std::sort( m_passwordChecks.begin(), m_passwordChecks.end() );
|
||||||
|
m_passwordChecksChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
for ( auto pc : m_passwordChecks )
|
for ( auto pc : m_passwordChecks )
|
||||||
{
|
{
|
||||||
QString s = pc.filter( pw1 );
|
QString s = pc.filter( pw1 );
|
||||||
@ -502,6 +508,8 @@ UsersPage::setReusePasswordDefault( bool checked )
|
|||||||
void
|
void
|
||||||
UsersPage::addPasswordCheck( const QString& key, const QVariant& value )
|
UsersPage::addPasswordCheck( const QString& key, const QVariant& value )
|
||||||
{
|
{
|
||||||
|
m_passwordChecksChanged = true;
|
||||||
|
|
||||||
if ( key == "minLength" )
|
if ( key == "minLength" )
|
||||||
{
|
{
|
||||||
add_check_minLength( m_passwordChecks, value );
|
add_check_minLength( m_passwordChecks, value );
|
||||||
@ -510,6 +518,16 @@ UsersPage::addPasswordCheck( const QString& key, const QVariant& value )
|
|||||||
{
|
{
|
||||||
add_check_maxLength( m_passwordChecks, value );
|
add_check_maxLength( m_passwordChecks, value );
|
||||||
}
|
}
|
||||||
|
else if ( key == "nonempty" )
|
||||||
|
{
|
||||||
|
if ( value.toBool() )
|
||||||
|
{
|
||||||
|
m_passwordChecks.push_back( PasswordCheck(
|
||||||
|
[]() { return QCoreApplication::translate( "PWQ", "Password is empty" ); },
|
||||||
|
[]( const QString& s ) { return !s.isEmpty(); },
|
||||||
|
PasswordCheck::Weight( 1 ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef CHECK_PWQUALITY
|
#ifdef CHECK_PWQUALITY
|
||||||
else if ( key == "libpwquality" )
|
else if ( key == "libpwquality" )
|
||||||
{
|
{
|
||||||
|
@ -90,6 +90,7 @@ private:
|
|||||||
Ui::Page_UserSetup* ui;
|
Ui::Page_UserSetup* ui;
|
||||||
|
|
||||||
PasswordCheckList m_passwordChecks;
|
PasswordCheckList m_passwordChecks;
|
||||||
|
bool m_passwordChecksChanged = false;
|
||||||
|
|
||||||
bool m_readyFullName;
|
bool m_readyFullName;
|
||||||
bool m_readyUsername;
|
bool m_readyUsername;
|
||||||
|
@ -58,8 +58,14 @@ setRootPassword: true
|
|||||||
doReusePassword: true
|
doReusePassword: true
|
||||||
|
|
||||||
# These are optional password-requirements that a distro can enforce
|
# These are optional password-requirements that a distro can enforce
|
||||||
# on the user. The values given in this sample file disable each check,
|
# on the user. The values given in this sample file set only very weak
|
||||||
# as if the check was not listed at all.
|
# validation settings.
|
||||||
|
#
|
||||||
|
# - nonempty rejects empty passwords
|
||||||
|
# - there are no length validations
|
||||||
|
# - libpwquality (if it is enabled at all) has no length of class
|
||||||
|
# restrictions, although it will still reject palindromes and
|
||||||
|
# dictionary words with these settings.
|
||||||
#
|
#
|
||||||
# Checks may be listed multiple times; each is checked separately,
|
# Checks may be listed multiple times; each is checked separately,
|
||||||
# and no effort is done to ensure that the checks are consistent
|
# and no effort is done to ensure that the checks are consistent
|
||||||
@ -84,6 +90,7 @@ doReusePassword: true
|
|||||||
# (That will show the box *Allow weak passwords* in the user-
|
# (That will show the box *Allow weak passwords* in the user-
|
||||||
# interface, and check it by default).
|
# interface, and check it by default).
|
||||||
passwordRequirements:
|
passwordRequirements:
|
||||||
|
nonempty: true
|
||||||
minLength: -1 # Password at least this many characters
|
minLength: -1 # Password at least this many characters
|
||||||
maxLength: -1 # Password at most this many characters
|
maxLength: -1 # Password at most this many characters
|
||||||
libpwquality:
|
libpwquality:
|
||||||
|
Loading…
Reference in New Issue
Block a user