[users] Apply coding style (lots of churn)

This commit is contained in:
Adriaan de Groot 2019-10-21 17:21:33 +02:00
parent 799f1131a9
commit eb90757063
13 changed files with 272 additions and 277 deletions

View File

@ -32,12 +32,12 @@
PasswordCheck::PasswordCheck() PasswordCheck::PasswordCheck()
: m_message() : m_message()
, m_accept( []( const QString& ){ return true; } ) , m_accept( []( const QString& ) { return true; } )
{ {
} }
PasswordCheck::PasswordCheck( const QString& m, AcceptFunc a ) PasswordCheck::PasswordCheck( const QString& m, AcceptFunc a )
: m_message( [m](){ return m; } ) : m_message( [m]() { return m; } )
, m_accept( a ) , m_accept( a )
{ {
} }
@ -52,21 +52,14 @@ DEFINE_CHECK_FUNC( minLength )
{ {
int minLength = -1; int minLength = -1;
if ( value.canConvert( QVariant::Int ) ) if ( value.canConvert( QVariant::Int ) )
{
minLength = value.toInt(); minLength = value.toInt();
}
if ( minLength > 0 ) if ( minLength > 0 )
{ {
cDebug() << Logger::SubEntry << "minLength set to" << minLength; cDebug() << Logger::SubEntry << "minLength set to" << minLength;
checks.push_back( checks.push_back( PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is too short" ); },
PasswordCheck( [minLength]( const QString& s ) { return s.length() >= minLength; } ) );
[]()
{
return QCoreApplication::translate( "PWQ", "Password is too short" );
},
[minLength]( const QString& s )
{
return s.length() >= minLength;
}
) );
} }
} }
@ -74,21 +67,14 @@ DEFINE_CHECK_FUNC( maxLength )
{ {
int maxLength = -1; int maxLength = -1;
if ( value.canConvert( QVariant::Int ) ) if ( value.canConvert( QVariant::Int ) )
{
maxLength = value.toInt(); maxLength = value.toInt();
}
if ( maxLength > 0 ) if ( maxLength > 0 )
{ {
cDebug() << Logger::SubEntry << "maxLength set to" << maxLength; cDebug() << Logger::SubEntry << "maxLength set to" << maxLength;
checks.push_back( checks.push_back( PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is too long" ); },
PasswordCheck( [maxLength]( const QString& s ) { return s.length() <= maxLength; } ) );
[]()
{
return QCoreApplication::translate("PWQ", "Password is too long" );
},
[maxLength]( const QString& s )
{
return s.length() <= maxLength;
}
) );
} }
} }
@ -101,15 +87,17 @@ DEFINE_CHECK_FUNC( maxLength )
*/ */
/// @brief Handle libpwquality using void* to represent a long /// @brief Handle libpwquality using void* to represent a long
static inline long mungeLong( void* p ) static inline long
mungeLong( void* p )
{ {
return static_cast<long>( reinterpret_cast<intptr_t>( p ) ); return static_cast< long >( reinterpret_cast< intptr_t >( p ) );
} }
/// @brief Handle libpwquality using void* to represent a char* /// @brief Handle libpwquality using void* to represent a char*
static inline const char* mungeString( void* p ) static inline const char*
mungeString( void* p )
{ {
return reinterpret_cast<const char*>( p ); return reinterpret_cast< const char* >( p );
} }
/** /**
@ -128,16 +116,10 @@ public:
{ {
} }
~PWSettingsHolder() ~PWSettingsHolder() { pwquality_free_settings( m_settings ); }
{
pwquality_free_settings( m_settings );
}
/// Sets an option via the configuration string @p v, <key>=<value> style. /// Sets an option via the configuration string @p v, <key>=<value> style.
int set( const QString& v ) int set( const QString& v ) { return pwquality_set_option( m_settings, v.toUtf8().constData() ); }
{
return pwquality_set_option( m_settings, v.toUtf8().constData() );
}
/// Checks the given password @p pwd against the current configuration /// Checks the given password @p pwd against the current configuration
int check( const QString& pwd ) int check( const QString& pwd )
@ -148,10 +130,7 @@ public:
return r; return r;
} }
bool hasExplanation() const bool hasExplanation() const { return m_rv < 0; }
{
return m_rv < 0;
}
/* This is roughly the same as the function pwquality_strerror, /* This is roughly the same as the function pwquality_strerror,
* only with QStrings instead, and using the Qt translation scheme. * only with QStrings instead, and using the Qt translation scheme.
@ -164,16 +143,21 @@ public:
m_auxerror = nullptr; m_auxerror = nullptr;
if ( m_rv >= arbitrary_minimum_strength ) if ( m_rv >= arbitrary_minimum_strength )
{
return QString(); return QString();
}
if ( m_rv >= 0 ) if ( m_rv >= 0 )
{
return QCoreApplication::translate( "PWQ", "Password is too weak" ); return QCoreApplication::translate( "PWQ", "Password is too weak" );
}
switch ( m_rv ) switch ( m_rv )
{ {
case PWQ_ERROR_MEM_ALLOC: case PWQ_ERROR_MEM_ALLOC:
if ( auxerror ) if ( auxerror )
{ {
QString s = QCoreApplication::translate( "PWQ", "Memory allocation error when setting '%1'" ).arg( mungeString( auxerror ) ); QString s = QCoreApplication::translate( "PWQ", "Memory allocation error when setting '%1'" )
.arg( mungeString( auxerror ) );
free( auxerror ); free( auxerror );
return s; return s;
} }
@ -189,58 +173,94 @@ public:
case PWQ_ERROR_USER_CHECK: case PWQ_ERROR_USER_CHECK:
return QCoreApplication::translate( "PWQ", "The password contains the user name in some form" ); return QCoreApplication::translate( "PWQ", "The password contains the user name in some form" );
case PWQ_ERROR_GECOS_CHECK: case PWQ_ERROR_GECOS_CHECK:
return QCoreApplication::translate( "PWQ", "The password contains words from the real name of the user in some form" ); return QCoreApplication::translate(
"PWQ", "The password contains words from the real name of the user in some form" );
case PWQ_ERROR_BAD_WORDS: case PWQ_ERROR_BAD_WORDS:
return QCoreApplication::translate( "PWQ", "The password contains forbidden words in some form" ); return QCoreApplication::translate( "PWQ", "The password contains forbidden words in some form" );
case PWQ_ERROR_MIN_DIGITS: case PWQ_ERROR_MIN_DIGITS:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains less than %1 digits" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ", "The password contains less than %1 digits" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ", "The password contains too few digits" ); return QCoreApplication::translate( "PWQ", "The password contains too few digits" );
case PWQ_ERROR_MIN_UPPERS: case PWQ_ERROR_MIN_UPPERS:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains less than %1 uppercase letters" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ", "The password contains less than %1 uppercase letters" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ", "The password contains too few uppercase letters" ); return QCoreApplication::translate( "PWQ", "The password contains too few uppercase letters" );
case PWQ_ERROR_MIN_LOWERS: case PWQ_ERROR_MIN_LOWERS:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains less than %1 lowercase letters" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ", "The password contains less than %1 lowercase letters" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ", "The password contains too few lowercase letters" ); return QCoreApplication::translate( "PWQ", "The password contains too few lowercase letters" );
case PWQ_ERROR_MIN_OTHERS: case PWQ_ERROR_MIN_OTHERS:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains less than %1 non-alphanumeric characters" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ",
"The password contains less than %1 non-alphanumeric characters" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ", "The password contains too few non-alphanumeric characters" ); return QCoreApplication::translate( "PWQ", "The password contains too few non-alphanumeric characters" );
case PWQ_ERROR_MIN_LENGTH: case PWQ_ERROR_MIN_LENGTH:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password is shorter than %1 characters" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ", "The password is shorter than %1 characters" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ", "The password is too short" ); return QCoreApplication::translate( "PWQ", "The password is too short" );
case PWQ_ERROR_ROTATED: case PWQ_ERROR_ROTATED:
return QCoreApplication::translate( "PWQ", "The password is just rotated old one" ); return QCoreApplication::translate( "PWQ", "The password is just rotated old one" );
case PWQ_ERROR_MIN_CLASSES: case PWQ_ERROR_MIN_CLASSES:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains less than %1 character classes" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ", "The password contains less than %1 character classes" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ", "The password does not contain enough character classes" ); return QCoreApplication::translate( "PWQ", "The password does not contain enough character classes" );
case PWQ_ERROR_MAX_CONSECUTIVE: case PWQ_ERROR_MAX_CONSECUTIVE:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains more than %1 same characters consecutively" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ",
"The password contains more than %1 same characters consecutively" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ", "The password contains too many same characters consecutively" ); return QCoreApplication::translate( "PWQ", "The password contains too many same characters consecutively" );
case PWQ_ERROR_MAX_CLASS_REPEAT: case PWQ_ERROR_MAX_CLASS_REPEAT:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains more than %1 characters of the same class consecutively" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ", "The password contains too many characters of the same class consecutively" ); return QCoreApplication::translate(
"PWQ", "The password contains more than %1 characters of the same class consecutively" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate(
"PWQ", "The password contains too many characters of the same class consecutively" );
case PWQ_ERROR_MAX_SEQUENCE: case PWQ_ERROR_MAX_SEQUENCE:
if ( auxerror ) if ( auxerror )
return QCoreApplication::translate( "PWQ", "The password contains monotonic sequence longer than %1 characters" ).arg( mungeLong( auxerror ) ); {
return QCoreApplication::translate( "PWQ", "The password contains too long of a monotonic character sequence" ); return QCoreApplication::translate(
"PWQ", "The password contains monotonic sequence longer than %1 characters" )
.arg( mungeLong( auxerror ) );
}
return QCoreApplication::translate( "PWQ",
"The password contains too long of a monotonic character sequence" );
case PWQ_ERROR_EMPTY_PASSWORD: case PWQ_ERROR_EMPTY_PASSWORD:
return QCoreApplication::translate( "PWQ", "No password supplied" ); return QCoreApplication::translate( "PWQ", "No password supplied" );
case PWQ_ERROR_RNG: case PWQ_ERROR_RNG:
return QCoreApplication::translate( "PWQ", "Cannot obtain random numbers from the RNG device" ); return QCoreApplication::translate( "PWQ", "Cannot obtain random numbers from the RNG device" );
case PWQ_ERROR_GENERATION_FAILED: case PWQ_ERROR_GENERATION_FAILED:
return QCoreApplication::translate( "PWQ", "Password generation failed - required entropy too low for settings" ); return QCoreApplication::translate( "PWQ",
"Password generation failed - required entropy too low for settings" );
case PWQ_ERROR_CRACKLIB_CHECK: case PWQ_ERROR_CRACKLIB_CHECK:
if ( auxerror ) if ( auxerror )
{ {
/* Here the string comes from cracklib, don't free? */ /* Here the string comes from cracklib, don't free? */
return QCoreApplication::translate( "PWQ", "The password fails the dictionary check - %1" ).arg( mungeString( auxerror ) ); return QCoreApplication::translate( "PWQ", "The password fails the dictionary check - %1" )
.arg( mungeString( auxerror ) );
} }
return QCoreApplication::translate( "PWQ", "The password fails the dictionary check" ); return QCoreApplication::translate( "PWQ", "The password fails the dictionary check" );
case PWQ_ERROR_UNKNOWN_SETTING: case PWQ_ERROR_UNKNOWN_SETTING:
@ -254,7 +274,8 @@ public:
case PWQ_ERROR_INTEGER: case PWQ_ERROR_INTEGER:
if ( auxerror ) if ( auxerror )
{ {
QString s = QCoreApplication::translate( "PWQ", "Bad integer value of setting - %1" ).arg( mungeString( auxerror ) ); QString s = QCoreApplication::translate( "PWQ", "Bad integer value of setting - %1" )
.arg( mungeString( auxerror ) );
free( auxerror ); free( auxerror );
return s; return s;
} }
@ -262,7 +283,8 @@ public:
case PWQ_ERROR_NON_INT_SETTING: case PWQ_ERROR_NON_INT_SETTING:
if ( auxerror ) if ( auxerror )
{ {
QString s = QCoreApplication::translate( "PWQ", "Setting %1 is not of integer type" ).arg( mungeString( auxerror ) ); QString s = QCoreApplication::translate( "PWQ", "Setting %1 is not of integer type" )
.arg( mungeString( auxerror ) );
free( auxerror ); free( auxerror );
return s; return s;
} }
@ -270,7 +292,8 @@ public:
case PWQ_ERROR_NON_STR_SETTING: case PWQ_ERROR_NON_STR_SETTING:
if ( auxerror ) if ( auxerror )
{ {
QString s = QCoreApplication::translate( "PWQ", "Setting %1 is not of string type" ).arg( mungeString( auxerror ) ); QString s = QCoreApplication::translate( "PWQ", "Setting %1 is not of string type" )
.arg( mungeString( auxerror ) );
free( auxerror ); free( auxerror );
return s; return s;
} }
@ -290,7 +313,7 @@ private:
pwquality_settings_t* m_settings; pwquality_settings_t* m_settings;
int m_rv; int m_rv;
void* m_auxerror; void* m_auxerror;
} ; };
DEFINE_CHECK_FUNC( libpwquality ) DEFINE_CHECK_FUNC( libpwquality )
{ {
@ -302,7 +325,7 @@ DEFINE_CHECK_FUNC( libpwquality )
QVariantList l = value.toList(); QVariantList l = value.toList();
unsigned int requirement_count = 0; unsigned int requirement_count = 0;
auto settings = std::make_shared<PWSettingsHolder>(); auto settings = std::make_shared< PWSettingsHolder >();
for ( const auto& v : l ) for ( const auto& v : l )
{ {
if ( v.type() == QVariant::String ) if ( v.type() == QVariant::String )
@ -310,7 +333,9 @@ DEFINE_CHECK_FUNC( libpwquality )
QString option = v.toString(); QString option = v.toString();
int r = settings->set( option ); int r = settings->set( option );
if ( r ) if ( r )
{
cWarning() << "unrecognized libpwquality setting" << option; cWarning() << "unrecognized libpwquality setting" << option;
}
else else
{ {
cDebug() << Logger::SubEntry << "libpwquality setting" << option; cDebug() << Logger::SubEntry << "libpwquality setting" << option;
@ -318,28 +343,27 @@ DEFINE_CHECK_FUNC( libpwquality )
} }
} }
else else
{
cWarning() << "unrecognized libpwquality setting" << v; cWarning() << "unrecognized libpwquality setting" << v;
} }
}
/* Something actually added? */ /* Something actually added? */
if ( requirement_count ) if ( requirement_count )
{ {
checks.push_back( checks.push_back( PasswordCheck( [settings]() { return settings->explanation(); },
PasswordCheck( [settings]( const QString& s ) {
[settings]()
{
return settings->explanation();
},
[settings]( const QString& s )
{
int r = settings->check( s ); int r = settings->check( s );
if ( r < 0 ) if ( r < 0 )
{
cWarning() << "libpwquality error" << r; cWarning() << "libpwquality error" << r;
else if ( r < settings->arbitrary_minimum_strength )
cDebug() << "Password strength" << r << "too low";
return r >= settings->arbitrary_minimum_strength;
} }
) ); else if ( r < settings->arbitrary_minimum_strength )
{
cDebug() << "Password strength" << r << "too low";
}
return r >= settings->arbitrary_minimum_strength;
} ) );
} }
} }
#endif #endif

View File

@ -35,8 +35,8 @@ class PasswordCheck
{ {
public: public:
/** Return true if the string is acceptable. */ /** Return true if the string is acceptable. */
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 */ /** Generate a @p message if @p filter returns true */
PasswordCheck( MessageFunc message, AcceptFunc filter ); PasswordCheck( MessageFunc message, AcceptFunc filter );
@ -50,17 +50,14 @@ public:
* according to this filter. Returns a message describing * according to this filter. Returns a message describing
* what is wrong if not. * what is wrong if not.
*/ */
QString filter( const QString& s ) const QString filter( const QString& s ) const { return m_accept( s ) ? QString() : m_message(); }
{
return m_accept( s ) ? QString() : m_message();
}
private: private:
MessageFunc m_message; MessageFunc m_message;
AcceptFunc m_accept; AcceptFunc m_accept;
} ; };
using PasswordCheckList = QVector<PasswordCheck>; using PasswordCheckList = QVector< PasswordCheck >;
/* Each of these functions adds a check (if possible) to the list /* Each of these functions adds a check (if possible) to the list
* of checks; they use the configuration value(s) from the * of checks; they use the configuration value(s) from the
@ -68,16 +65,14 @@ using PasswordCheckList = QVector<PasswordCheck>;
* may skip adding a check, and do nothing (it should log * may skip adding a check, and do nothing (it should log
* an error, though). * an error, though).
*/ */
#define _xDEFINE_CHECK_FUNC(x) \ #define _xDEFINE_CHECK_FUNC( x ) add_check_##x( PasswordCheckList& checks, const QVariant& value )
add_check_##x( PasswordCheckList& checks, const QVariant& value ) #define DEFINE_CHECK_FUNC( x ) void _xDEFINE_CHECK_FUNC( x )
#define DEFINE_CHECK_FUNC(x) void _xDEFINE_CHECK_FUNC(x) #define DECLARE_CHECK_FUNC( x ) void _xDEFINE_CHECK_FUNC( x );
#define DECLARE_CHECK_FUNC(x) void _xDEFINE_CHECK_FUNC(x);
DECLARE_CHECK_FUNC(minLength) DECLARE_CHECK_FUNC( minLength )
DECLARE_CHECK_FUNC(maxLength) DECLARE_CHECK_FUNC( maxLength )
#ifdef HAVE_LIBPWQUALITY #ifdef HAVE_LIBPWQUALITY
DECLARE_CHECK_FUNC(libpwquality) DECLARE_CHECK_FUNC( libpwquality )
#endif #endif
#endif #endif

View File

@ -19,10 +19,10 @@
#include <CreateUserJob.h> #include <CreateUserJob.h>
#include "JobQueue.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "utils/Logger.h" #include "JobQueue.h"
#include "utils/CalamaresUtilsSystem.h" #include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <QDateTime> #include <QDateTime>
#include <QDir> #include <QDir>
@ -72,17 +72,20 @@ CreateUserJob::exec()
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
QDir destDir( gs->value( "rootMountPoint" ).toString() ); QDir destDir( gs->value( "rootMountPoint" ).toString() );
if ( gs->contains( "sudoersGroup" ) && if ( gs->contains( "sudoersGroup" ) && !gs->value( "sudoersGroup" ).toString().isEmpty() )
!gs->value( "sudoersGroup" ).toString().isEmpty() )
{ {
QFileInfo sudoersFi( destDir.absoluteFilePath( "etc/sudoers.d/10-installer" ) ); QFileInfo sudoersFi( destDir.absoluteFilePath( "etc/sudoers.d/10-installer" ) );
if ( !sudoersFi.absoluteDir().exists() ) if ( !sudoersFi.absoluteDir().exists() )
{
return Calamares::JobResult::error( tr( "Sudoers dir is not writable." ) ); return Calamares::JobResult::error( tr( "Sudoers dir is not writable." ) );
}
QFile sudoersFile( sudoersFi.absoluteFilePath() ); QFile sudoersFile( sudoersFi.absoluteFilePath() );
if (!sudoersFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) if ( !sudoersFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
{
return Calamares::JobResult::error( tr( "Cannot create sudoers file for writing." ) ); return Calamares::JobResult::error( tr( "Cannot create sudoers file for writing." ) );
}
QString sudoersGroup = gs->value( "sudoersGroup" ).toString(); QString sudoersGroup = gs->value( "sudoersGroup" ).toString();
@ -96,11 +99,12 @@ CreateUserJob::exec()
QFileInfo groupsFi( destDir.absoluteFilePath( "etc/group" ) ); QFileInfo groupsFi( destDir.absoluteFilePath( "etc/group" ) );
QFile groupsFile( groupsFi.absoluteFilePath() ); QFile groupsFile( groupsFi.absoluteFilePath() );
if ( !groupsFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) if ( !groupsFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
{
return Calamares::JobResult::error( tr( "Cannot open groups file for reading." ) ); return Calamares::JobResult::error( tr( "Cannot open groups file for reading." ) );
}
QString groupsData = QString::fromLocal8Bit( groupsFile.readAll() ); QString groupsData = QString::fromLocal8Bit( groupsFile.readAll() );
QStringList groupsLines = groupsData.split( '\n' ); QStringList groupsLines = groupsData.split( '\n' );
for ( QStringList::iterator it = groupsLines.begin(); for ( QStringList::iterator it = groupsLines.begin(); it != groupsLines.end(); ++it )
it != groupsLines.end(); ++it )
{ {
int indexOfFirstToDrop = it->indexOf( ':' ); int indexOfFirstToDrop = it->indexOf( ':' );
it->truncate( indexOfFirstToDrop ); it->truncate( indexOfFirstToDrop );
@ -108,15 +112,13 @@ CreateUserJob::exec()
foreach ( const QString& group, m_defaultGroups ) foreach ( const QString& group, m_defaultGroups )
if ( !groupsLines.contains( group ) ) if ( !groupsLines.contains( group ) )
CalamaresUtils::System::instance()-> CalamaresUtils::System::instance()->targetEnvCall( { "groupadd", group } );
targetEnvCall( { "groupadd", group } );
QString defaultGroups = m_defaultGroups.join( ',' ); QString defaultGroups = m_defaultGroups.join( ',' );
if ( m_autologin ) if ( m_autologin )
{ {
QString autologinGroup; QString autologinGroup;
if ( gs->contains( "autologinGroup" ) && if ( gs->contains( "autologinGroup" ) && !gs->value( "autologinGroup" ).toString().isEmpty() )
!gs->value( "autologinGroup" ).toString().isEmpty() )
{ {
autologinGroup = gs->value( "autologinGroup" ).toString(); autologinGroup = gs->value( "autologinGroup" ).toString();
CalamaresUtils::System::instance()->targetEnvCall( { "groupadd", autologinGroup } ); CalamaresUtils::System::instance()->targetEnvCall( { "groupadd", autologinGroup } );
@ -131,26 +133,20 @@ CreateUserJob::exec()
QDir existingHome( destDir.absolutePath() + shellFriendlyHome ); QDir existingHome( destDir.absolutePath() + shellFriendlyHome );
if ( existingHome.exists() ) if ( existingHome.exists() )
{ {
QString backupDirName = "dotfiles_backup_" + QString backupDirName = "dotfiles_backup_" + QDateTime::currentDateTime().toString( "yyyy-MM-dd_HH-mm-ss" );
QDateTime::currentDateTime()
.toString( "yyyy-MM-dd_HH-mm-ss" );
existingHome.mkdir( backupDirName ); existingHome.mkdir( backupDirName );
CalamaresUtils::System::instance()-> CalamaresUtils::System::instance()->targetEnvCall(
targetEnvCall( { "sh", { "sh", "-c", "mv -f " + shellFriendlyHome + "/.* " + shellFriendlyHome + "/" + backupDirName } );
"-c",
"mv -f " +
shellFriendlyHome + "/.* " +
shellFriendlyHome + "/" +
backupDirName
} );
} }
} }
QStringList useradd{ "useradd", "-m", "-U" }; QStringList useradd { "useradd", "-m", "-U" };
QString shell = gs->value( "userShell" ).toString(); QString shell = gs->value( "userShell" ).toString();
if ( !shell.isEmpty() ) if ( !shell.isEmpty() )
{
useradd << "-s" << shell; useradd << "-s" << shell;
}
useradd << "-c" << m_fullName; useradd << "-c" << m_fullName;
useradd << m_userName; useradd << m_userName;
@ -161,8 +157,8 @@ CreateUserJob::exec()
return commandResult.explainProcess( useradd, std::chrono::seconds( 10 ) /* bogus timeout */ ); return commandResult.explainProcess( useradd, std::chrono::seconds( 10 ) /* bogus timeout */ );
} }
commandResult = CalamaresUtils::System::instance()->targetEnvCommand( commandResult
{ "usermod", "-aG", defaultGroups, m_userName } ); = CalamaresUtils::System::instance()->targetEnvCommand( { "usermod", "-aG", defaultGroups, m_userName } );
if ( commandResult.getExitCode() ) if ( commandResult.getExitCode() )
{ {
cError() << "usermod failed" << commandResult.getExitCode(); cError() << "usermod failed" << commandResult.getExitCode();
@ -171,8 +167,7 @@ CreateUserJob::exec()
QString userGroup = QString( "%1:%2" ).arg( m_userName ).arg( m_userName ); QString userGroup = QString( "%1:%2" ).arg( m_userName ).arg( m_userName );
QString homeDir = QString( "/home/%1" ).arg( m_userName ); QString homeDir = QString( "/home/%1" ).arg( m_userName );
commandResult = CalamaresUtils::System::instance()->targetEnvCommand( commandResult = CalamaresUtils::System::instance()->targetEnvCommand( { "chown", "-R", userGroup, homeDir } );
{ "chown", "-R", userGroup, homeDir } );
if ( commandResult.getExitCode() ) if ( commandResult.getExitCode() )
{ {
cError() << "chown failed" << commandResult.getExitCode(); cError() << "chown failed" << commandResult.getExitCode();

View File

@ -27,10 +27,7 @@ class CreateUserJob : public Calamares::Job
{ {
Q_OBJECT Q_OBJECT
public: public:
CreateUserJob( const QString& userName, CreateUserJob( const QString& userName, const QString& fullName, bool autologin, const QStringList& defaultGroups );
const QString& fullName,
bool autologin,
const QStringList& defaultGroups );
QString prettyName() const override; QString prettyName() const override;
QString prettyDescription() const override; QString prettyDescription() const override;
QString prettyStatusMessage() const override; QString prettyStatusMessage() const override;

View File

@ -24,13 +24,9 @@
QTEST_GUILESS_MAIN( PasswordTests ) QTEST_GUILESS_MAIN( PasswordTests )
PasswordTests::PasswordTests() PasswordTests::PasswordTests() {}
{
}
PasswordTests::~PasswordTests() PasswordTests::~PasswordTests() {}
{
}
void void
PasswordTests::initTestCase() PasswordTests::initTestCase()

View File

@ -21,11 +21,11 @@
#include "SetHostNameJob.h" #include "SetHostNameJob.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "utils/Logger.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "utils/Logger.h"
#include <QFile>
#include <QDir> #include <QDir>
#include <QFile>
SetHostNameJob::SetHostNameJob( const QString& hostname ) SetHostNameJob::SetHostNameJob( const QString& hostname )
: Calamares::Job() : Calamares::Job()
@ -33,7 +33,8 @@ SetHostNameJob::SetHostNameJob( const QString& hostname )
{ {
} }
QString SetHostNameJob::prettyName() const QString
SetHostNameJob::prettyName() const
{ {
return tr( "Set hostname %1" ).arg( m_hostname ); return tr( "Set hostname %1" ).arg( m_hostname );
} }
@ -52,7 +53,8 @@ SetHostNameJob::prettyStatusMessage() const
return tr( "Setting hostname %1." ).arg( m_hostname ); return tr( "Setting hostname %1." ).arg( m_hostname );
} }
Calamares::JobResult SetHostNameJob::exec() Calamares::JobResult
SetHostNameJob::exec()
{ {
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
@ -90,11 +92,21 @@ Calamares::JobResult SetHostNameJob::exec()
// We also need to write the appropriate entries for /etc/hosts // We also need to write the appropriate entries for /etc/hosts
QTextStream hostsfileout( &hostsfile ); QTextStream hostsfileout( &hostsfile );
// ipv4 support // ipv4 support
hostsfileout << "127.0.0.1" << "\t" << "localhost" << "\n"; hostsfileout << "127.0.0.1"
hostsfileout << "127.0.1.1" << "\t" << m_hostname << "\n"; << "\t"
<< "localhost"
<< "\n";
hostsfileout << "127.0.1.1"
<< "\t" << m_hostname << "\n";
// ipv6 support // ipv6 support
hostsfileout << "::1" << "\t" << "localhost ip6-localhost ip6-loopback" << "\n"; hostsfileout << "::1"
hostsfileout << "ff02::1 ip6-allnodes" << "\n" << "ff02::2 ip6-allrouters" << "\n"; << "\t"
<< "localhost ip6-localhost ip6-loopback"
<< "\n";
hostsfileout << "ff02::1 ip6-allnodes"
<< "\n"
<< "ff02::2 ip6-allrouters"
<< "\n";
hostsfile.close(); hostsfile.close();
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();

View File

@ -31,6 +31,7 @@ public:
QString prettyDescription() const override; QString prettyDescription() const override;
QString prettyStatusMessage() const override; QString prettyStatusMessage() const override;
Calamares::JobResult exec() override; Calamares::JobResult exec() override;
private: private:
const QString m_hostname; const QString m_hostname;
}; };

View File

@ -19,10 +19,10 @@
#include <SetPasswordJob.h> #include <SetPasswordJob.h>
#include "JobQueue.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "utils/Logger.h" #include "JobQueue.h"
#include "utils/CalamaresUtilsSystem.h" #include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <QDir> #include <QDir>
@ -58,29 +58,27 @@ SetPasswordJob::prettyStatusMessage() const
/// Returns a modular hashing salt for method 6 (SHA512) with a 16 character random salt. /// Returns a modular hashing salt for method 6 (SHA512) with a 16 character random salt.
QString QString
SetPasswordJob::make_salt(int length) SetPasswordJob::make_salt( int length )
{ {
Q_ASSERT(length >= 8); Q_ASSERT( length >= 8 );
Q_ASSERT(length <= 128); Q_ASSERT( length <= 128 );
static const char salt_chars[] = { static const char salt_chars[] = { '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
'.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
static_assert( sizeof(salt_chars) == 64, "Missing salt_chars"); static_assert( sizeof( salt_chars ) == 64, "Missing salt_chars" );
std::random_device r; std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; std::seed_seq seed { r(), r(), r(), r(), r(), r(), r(), r() };
std::mt19937_64 twister(seed); std::mt19937_64 twister( seed );
std::uint64_t next; std::uint64_t next;
int current_length = 0; int current_length = 0;
QString salt_string; QString salt_string;
salt_string.reserve(length + 10); salt_string.reserve( length + 10 );
while ( current_length < length ) while ( current_length < length )
{ {
@ -89,13 +87,15 @@ SetPasswordJob::make_salt(int length)
// to a single salt character. // to a single salt character.
for ( unsigned int char_count = 0; char_count < 10; ++char_count ) for ( unsigned int char_count = 0; char_count < 10; ++char_count )
{ {
char c = salt_chars[next & 0b0111111]; char c = salt_chars[ next & 0b0111111 ];
next >>= 6; next >>= 6;
salt_string.append( c ); salt_string.append( c );
if (++current_length >= length) if ( ++current_length >= length )
{
break; break;
} }
} }
}
salt_string.truncate( length ); salt_string.truncate( length );
salt_string.insert( 0, "$6$" ); salt_string.insert( 0, "$6$" );
@ -112,34 +112,21 @@ SetPasswordJob::exec()
return Calamares::JobResult::error( tr( "Bad destination system path." ), return Calamares::JobResult::error( tr( "Bad destination system path." ),
tr( "rootMountPoint is %1" ).arg( destDir.absolutePath() ) ); tr( "rootMountPoint is %1" ).arg( destDir.absolutePath() ) );
if ( m_userName == "root" && if ( m_userName == "root" && m_newPassword.isEmpty() ) //special case for disabling root account
m_newPassword.isEmpty() ) //special case for disabling root account
{ {
int ec = CalamaresUtils::System::instance()-> int ec = CalamaresUtils::System::instance()->targetEnvCall( { "passwd", "-dl", m_userName } );
targetEnvCall( { "passwd",
"-dl",
m_userName } );
if ( ec ) if ( ec )
return Calamares::JobResult::error( tr( "Cannot disable root account." ), return Calamares::JobResult::error( tr( "Cannot disable root account." ),
tr( "passwd terminated with error code %1." ) tr( "passwd terminated with error code %1." ).arg( ec ) );
.arg( ec ) );
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();
} }
QString encrypted = QString::fromLatin1( QString encrypted = QString::fromLatin1( crypt( m_newPassword.toUtf8(), make_salt( 16 ).toUtf8() ) );
crypt( m_newPassword.toUtf8(),
make_salt( 16 ).toUtf8() ) );
int ec = CalamaresUtils::System::instance()-> int ec = CalamaresUtils::System::instance()->targetEnvCall( { "usermod", "-p", encrypted, m_userName } );
targetEnvCall( { "usermod",
"-p",
encrypted,
m_userName } );
if ( ec ) if ( ec )
return Calamares::JobResult::error( tr( "Cannot set password for user %1." ) return Calamares::JobResult::error( tr( "Cannot set password for user %1." ).arg( m_userName ),
.arg( m_userName ), tr( "usermod terminated with error code %1." ).arg( ec ) );
tr( "usermod terminated with error code %1." )
.arg( ec ) );
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();
} }

View File

@ -27,13 +27,12 @@ class SetPasswordJob : public Calamares::Job
{ {
Q_OBJECT Q_OBJECT
public: public:
SetPasswordJob( const QString& userName, SetPasswordJob( const QString& userName, const QString& newPassword );
const QString& newPassword );
QString prettyName() const override; QString prettyName() const override;
QString prettyStatusMessage() const override; QString prettyStatusMessage() const override;
Calamares::JobResult exec() override; Calamares::JobResult exec() override;
static QString make_salt(int length); static QString make_salt( int length );
private: private:
QString m_userName; QString m_userName;

View File

@ -27,8 +27,8 @@
#include "ui_page_usersetup.h" #include "ui_page_usersetup.h"
#include "CreateUserJob.h" #include "CreateUserJob.h"
#include "SetPasswordJob.h"
#include "SetHostNameJob.h" #include "SetHostNameJob.h"
#include "SetPasswordJob.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "JobQueue.h" #include "JobQueue.h"
@ -74,30 +74,19 @@ UsersPage::UsersPage( QWidget* parent )
ui->setupUi( this ); ui->setupUi( this );
// Connect signals and slots // Connect signals and slots
connect( ui->textBoxFullName, &QLineEdit::textEdited, connect( ui->textBoxFullName, &QLineEdit::textEdited, this, &UsersPage::onFullNameTextEdited );
this, &UsersPage::onFullNameTextEdited ); connect( ui->textBoxUsername, &QLineEdit::textEdited, this, &UsersPage::onUsernameTextEdited );
connect( ui->textBoxUsername, &QLineEdit::textEdited, connect( ui->textBoxHostname, &QLineEdit::textEdited, this, &UsersPage::onHostnameTextEdited );
this, &UsersPage::onUsernameTextEdited ); connect( ui->textBoxUserPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged );
connect( ui->textBoxHostname, &QLineEdit::textEdited, connect( ui->textBoxUserVerifiedPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged );
this, &UsersPage::onHostnameTextEdited ); connect( ui->textBoxRootPassword, &QLineEdit::textChanged, this, &UsersPage::onRootPasswordTextChanged );
connect( ui->textBoxUserPassword, &QLineEdit::textChanged, connect( ui->textBoxVerifiedRootPassword, &QLineEdit::textChanged, this, &UsersPage::onRootPasswordTextChanged );
this, &UsersPage::onPasswordTextChanged ); connect( ui->checkBoxValidatePassword, &QCheckBox::stateChanged, this, [this]( int checked ) {
connect( ui->textBoxUserVerifiedPassword, &QLineEdit::textChanged,
this, &UsersPage::onPasswordTextChanged );
connect( ui->textBoxRootPassword, &QLineEdit::textChanged,
this, &UsersPage::onRootPasswordTextChanged );
connect( ui->textBoxVerifiedRootPassword, &QLineEdit::textChanged,
this, &UsersPage::onRootPasswordTextChanged );
connect( ui->checkBoxValidatePassword, &QCheckBox::stateChanged,
this, [this]( int checked )
{
onPasswordTextChanged( ui->textBoxUserPassword->text() ); onPasswordTextChanged( ui->textBoxUserPassword->text() );
onRootPasswordTextChanged( ui->textBoxRootPassword->text() ); onRootPasswordTextChanged( ui->textBoxRootPassword->text() );
checkReady( isReady() ); checkReady( isReady() );
} ); } );
connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( int checked ) {
this, [this]( int checked )
{
ui->labelChooseRootPassword->setVisible( !checked ); ui->labelChooseRootPassword->setVisible( !checked );
ui->labelExtraRootPassword->setVisible( !checked ); ui->labelExtraRootPassword->setVisible( !checked );
ui->labelRootPassword->setVisible( !checked ); ui->labelRootPassword->setVisible( !checked );
@ -117,26 +106,22 @@ UsersPage::UsersPage( QWidget* parent )
// Don't expand the explanations to "stupid wide", but keep them vaguely as-wide-as // Don't expand the explanations to "stupid wide", but keep them vaguely as-wide-as
// the things they are explaining. // the things they are explaining.
int boxWidth = qMax( qMax( ui->textBoxUsername->width(), ui->textBoxHostname->width() ), ui->textBoxUserPassword->width() ); int boxWidth
= qMax( qMax( ui->textBoxUsername->width(), ui->textBoxHostname->width() ), ui->textBoxUserPassword->width() );
ui->username_extra_label_2->setMaximumWidth( 3 * boxWidth ); ui->username_extra_label_2->setMaximumWidth( 3 * boxWidth );
ui->hostname_extra_label_2->setMaximumWidth( 3 * boxWidth ); ui->hostname_extra_label_2->setMaximumWidth( 3 * boxWidth );
ui->password_extra_label_3->setMaximumWidth( 3 * boxWidth ); ui->password_extra_label_3->setMaximumWidth( 3 * boxWidth );
CALAMARES_RETRANSLATE( CALAMARES_RETRANSLATE(
ui->retranslateUi( this ); ui->retranslateUi( this ); if ( Calamares::Settings::instance()->isSetupMode() ) {
if ( Calamares::Settings::instance()->isSetupMode() )
{
ui->username_extra_label_2->setText( tr( "<small>If more than one person will " ui->username_extra_label_2->setText( tr( "<small>If more than one person will "
"use this computer, you can create multiple " "use this computer, you can create multiple "
"accounts after setup.</small>" ) ); "accounts after setup.</small>" ) );
} } else {
else
{
ui->username_extra_label_2->setText( tr( "<small>If more than one person will " ui->username_extra_label_2->setText( tr( "<small>If more than one person will "
"use this computer, you can create multiple " "use this computer, you can create multiple "
"accounts after installation.</small>" ) ); "accounts after installation.</small>" ) );
} } )
)
} }
@ -149,12 +134,11 @@ UsersPage::~UsersPage()
bool bool
UsersPage::isReady() UsersPage::isReady()
{ {
bool readyFields = m_readyFullName && bool readyFields = m_readyFullName && m_readyHostname && m_readyPassword && m_readyUsername;
m_readyHostname &&
m_readyPassword &&
m_readyUsername;
if ( !m_writeRootPassword || ui->checkBoxReusePassword->isChecked() ) if ( !m_writeRootPassword || ui->checkBoxReusePassword->isChecked() )
{
return readyFields; return readyFields;
}
return readyFields && m_readyRootPassword; return readyFields && m_readyRootPassword;
} }
@ -165,32 +149,30 @@ UsersPage::createJobs( const QStringList& defaultGroupsList )
{ {
QList< Calamares::job_ptr > list; QList< Calamares::job_ptr > list;
if ( !isReady() ) if ( !isReady() )
{
return list; return list;
}
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
Calamares::Job* j; Calamares::Job* j;
j = new CreateUserJob( ui->textBoxUsername->text(), j = new CreateUserJob( ui->textBoxUsername->text(),
ui->textBoxFullName->text().isEmpty() ? ui->textBoxFullName->text().isEmpty() ? ui->textBoxUsername->text()
ui->textBoxUsername->text() : : ui->textBoxFullName->text(),
ui->textBoxFullName->text(),
ui->checkBoxAutoLogin->isChecked(), ui->checkBoxAutoLogin->isChecked(),
defaultGroupsList ); defaultGroupsList );
list.append( Calamares::job_ptr( j ) ); list.append( Calamares::job_ptr( j ) );
j = new SetPasswordJob( ui->textBoxUsername->text(), j = new SetPasswordJob( ui->textBoxUsername->text(), ui->textBoxUserPassword->text() );
ui->textBoxUserPassword->text() );
list.append( Calamares::job_ptr( j ) ); list.append( Calamares::job_ptr( j ) );
if ( m_writeRootPassword ) if ( m_writeRootPassword )
{ {
gs->insert( "reuseRootPassword", ui->checkBoxReusePassword->isChecked() ); gs->insert( "reuseRootPassword", ui->checkBoxReusePassword->isChecked() );
if ( ui->checkBoxReusePassword->isChecked() ) if ( ui->checkBoxReusePassword->isChecked() )
j = new SetPasswordJob( "root", j = new SetPasswordJob( "root", ui->textBoxUserPassword->text() );
ui->textBoxUserPassword->text() );
else else
j = new SetPasswordJob( "root", j = new SetPasswordJob( "root", ui->textBoxRootPassword->text() );
ui->textBoxRootPassword->text() );
list.append( Calamares::job_ptr( j ) ); list.append( Calamares::job_ptr( j ) );
} }
else else
@ -205,7 +187,9 @@ UsersPage::createJobs( const QStringList& defaultGroupsList )
gs->insert( "hostname", ui->textBoxHostname->text() ); gs->insert( "hostname", ui->textBoxHostname->text() );
if ( ui->checkBoxAutoLogin->isChecked() ) if ( ui->checkBoxAutoLogin->isChecked() )
{
gs->insert( "autologinUser", ui->textBoxUsername->text() ); gs->insert( "autologinUser", ui->textBoxUsername->text() );
}
gs->insert( "username", ui->textBoxUsername->text() ); gs->insert( "username", ui->textBoxUsername->text() );
gs->insert( "password", CalamaresUtils::obscure( ui->textBoxUserPassword->text() ) ); gs->insert( "password", CalamaresUtils::obscure( ui->textBoxUserPassword->text() ) );
@ -237,16 +221,19 @@ UsersPage::onFullNameTextEdited( const QString& textRef )
ui->labelFullNameError->clear(); ui->labelFullNameError->clear();
ui->labelFullName->clear(); ui->labelFullName->clear();
if ( !m_customUsername ) if ( !m_customUsername )
{
ui->textBoxUsername->clear(); ui->textBoxUsername->clear();
}
if ( !m_customHostname ) if ( !m_customHostname )
{
ui->textBoxHostname->clear(); ui->textBoxHostname->clear();
}
m_readyFullName = false; m_readyFullName = false;
} }
else else
{ {
ui->labelFullName->setPixmap( CalamaresUtils::defaultPixmap( CalamaresUtils::Yes, ui->labelFullName->setPixmap(
CalamaresUtils::Original, CalamaresUtils::defaultPixmap( CalamaresUtils::Yes, CalamaresUtils::Original, ui->labelFullName->size() ) );
ui->labelFullName->size() ) );
m_readyFullName = true; m_readyFullName = true;
fillSuggestions(); fillSuggestions();
} }
@ -259,8 +246,7 @@ UsersPage::fillSuggestions()
{ {
QString fullName = ui->textBoxFullName->text(); QString fullName = ui->textBoxFullName->text();
QRegExp rx( "[^a-zA-Z0-9 ]", Qt::CaseInsensitive ); QRegExp rx( "[^a-zA-Z0-9 ]", Qt::CaseInsensitive );
QString cleanName = CalamaresUtils::removeDiacritics( fullName ) QString cleanName = CalamaresUtils::removeDiacritics( fullName ).toLower().replace( rx, " " ).simplified();
.toLower().replace( rx, " " ).simplified();
QStringList cleanParts = cleanName.split( ' ' ); QStringList cleanParts = cleanName.split( ' ' );
if ( !m_customUsername ) if ( !m_customUsername )
@ -271,8 +257,10 @@ UsersPage::fillSuggestions()
for ( int i = 1; i < cleanParts.length(); ++i ) for ( int i = 1; i < cleanParts.length(); ++i )
{ {
if ( !cleanParts.value( i ).isEmpty() ) if ( !cleanParts.value( i ).isEmpty() )
{
usernameSuggestion.append( cleanParts.value( i ).at( 0 ) ); usernameSuggestion.append( cleanParts.value( i ).at( 0 ) );
} }
}
if ( USERNAME_RX.indexIn( usernameSuggestion ) != -1 ) if ( USERNAME_RX.indexIn( usernameSuggestion ) != -1 )
{ {
ui->textBoxUsername->setText( usernameSuggestion ); ui->textBoxUsername->setText( usernameSuggestion );
@ -322,13 +310,14 @@ UsersPage::validateUsernameText( const QString& textRef )
} }
else if ( text.length() > USERNAME_MAX_LENGTH ) else if ( text.length() > USERNAME_MAX_LENGTH )
{ {
labelError( ui->labelUsername, ui->labelUsernameError, labelError( ui->labelUsername, ui->labelUsernameError, tr( "Your username is too long." ) );
tr( "Your username is too long." ) );
m_readyUsername = false; m_readyUsername = false;
} }
else if ( val.validate( text, pos ) == QValidator::Invalid ) else if ( val.validate( text, pos ) == QValidator::Invalid )
{ {
labelError( ui->labelUsername, ui->labelUsernameError, labelError(
ui->labelUsername,
ui->labelUsernameError,
tr( "Your username contains invalid characters. Only lowercase letters and numbers are allowed." ) ); tr( "Your username contains invalid characters. Only lowercase letters and numbers are allowed." ) );
m_readyUsername = false; m_readyUsername = false;
} }
@ -362,23 +351,22 @@ UsersPage::validateHostnameText( const QString& textRef )
{ {
ui->labelHostnameError->clear(); ui->labelHostnameError->clear();
ui->labelHostname->clear(); ui->labelHostname->clear();
m_readyHostname= false; m_readyHostname = false;
} }
else if ( text.length() < HOSTNAME_MIN_LENGTH ) else if ( text.length() < HOSTNAME_MIN_LENGTH )
{ {
labelError( ui->labelHostname, ui->labelHostnameError, labelError( ui->labelHostname, ui->labelHostnameError, tr( "Your hostname is too short." ) );
tr( "Your hostname is too short." ) );
m_readyHostname = false; m_readyHostname = false;
} }
else if ( text.length() > HOSTNAME_MAX_LENGTH ) else if ( text.length() > HOSTNAME_MAX_LENGTH )
{ {
labelError( ui->labelHostname, ui->labelHostnameError, labelError( ui->labelHostname, ui->labelHostnameError, tr( "Your hostname is too long." ) );
tr( "Your hostname is too long." ) );
m_readyHostname = false; m_readyHostname = false;
} }
else if ( val.validate( text, pos ) == QValidator::Invalid ) else if ( val.validate( text, pos ) == QValidator::Invalid )
{ {
labelError( ui->labelHostname, ui->labelHostnameError, labelError( ui->labelHostname,
ui->labelHostnameError,
tr( "Your hostname contains invalid characters. Only letters, numbers and dashes are allowed." ) ); tr( "Your hostname contains invalid characters. Only letters, numbers and dashes are allowed." ) );
m_readyHostname = false; m_readyHostname = false;
} }
@ -407,8 +395,7 @@ UsersPage::onPasswordTextChanged( const QString& )
} }
else if ( pw1 != pw2 ) else if ( pw1 != pw2 )
{ {
labelError( ui->labelUserPassword, ui->labelUserPasswordError, labelError( ui->labelUserPassword, ui->labelUserPasswordError, tr( "Your passwords do not match!" ) );
tr( "Your passwords do not match!" ) );
m_readyPassword = false; m_readyPassword = false;
} }
else else
@ -453,8 +440,7 @@ UsersPage::onRootPasswordTextChanged( const QString& )
} }
else if ( pw1 != pw2 ) else if ( pw1 != pw2 )
{ {
labelError( ui->labelRootPassword, ui->labelRootPasswordError, labelError( ui->labelRootPassword, ui->labelRootPasswordError, tr( "Your passwords do not match!" ) );
tr( "Your passwords do not match!" ) );
m_readyRootPassword = false; m_readyRootPassword = false;
} }
else else
@ -529,5 +515,7 @@ UsersPage::addPasswordCheck( const QString& key, const QVariant& value )
} }
#endif // CHECK_PWQUALITY #endif // CHECK_PWQUALITY
else else
{
cWarning() << "Unknown password-check key" << key; cWarning() << "Unknown password-check key" << key;
}
} }

View File

@ -29,22 +29,23 @@
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "JobQueue.h" #include "JobQueue.h"
CALAMARES_PLUGIN_FACTORY_DEFINITION( UsersViewStepFactory, registerPlugin<UsersViewStep>(); ) CALAMARES_PLUGIN_FACTORY_DEFINITION( UsersViewStepFactory, registerPlugin< UsersViewStep >(); )
UsersViewStep::UsersViewStep( QObject* parent ) UsersViewStep::UsersViewStep( QObject* parent )
: Calamares::ViewStep( parent ) : Calamares::ViewStep( parent )
, m_widget( new UsersPage() ) , m_widget( new UsersPage() )
{ {
emit nextStatusChanged( true ); emit nextStatusChanged( true );
connect( m_widget, &UsersPage::checkReady, connect( m_widget, &UsersPage::checkReady, this, &UsersViewStep::nextStatusChanged );
this, &UsersViewStep::nextStatusChanged );
} }
UsersViewStep::~UsersViewStep() UsersViewStep::~UsersViewStep()
{ {
if ( m_widget && m_widget->parent() == nullptr ) if ( m_widget && m_widget->parent() == nullptr )
{
m_widget->deleteLater(); m_widget->deleteLater();
}
} }
@ -116,80 +117,80 @@ UsersViewStep::onLeave()
void void
UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{ {
if ( configurationMap.contains( "defaultGroups" ) && if ( configurationMap.contains( "defaultGroups" )
configurationMap.value( "defaultGroups" ).type() == QVariant::List ) && configurationMap.value( "defaultGroups" ).type() == QVariant::List )
{ {
m_defaultGroups = configurationMap.value( "defaultGroups" ).toStringList(); m_defaultGroups = configurationMap.value( "defaultGroups" ).toStringList();
} }
else else
{ {
cWarning() << "Using fallback groups. Please check defaultGroups in users.conf"; cWarning() << "Using fallback groups. Please check defaultGroups in users.conf";
m_defaultGroups = QStringList{ "lp", "video", "network", "storage", "wheel", "audio" }; m_defaultGroups = QStringList { "lp", "video", "network", "storage", "wheel", "audio" };
} }
if ( configurationMap.contains( "autologinGroup" ) && if ( configurationMap.contains( "autologinGroup" )
configurationMap.value( "autologinGroup" ).type() == QVariant::String ) && configurationMap.value( "autologinGroup" ).type() == QVariant::String )
{ {
Calamares::JobQueue::instance()->globalStorage()->insert( "autologinGroup", Calamares::JobQueue::instance()->globalStorage()->insert(
configurationMap.value( "autologinGroup" ).toString() ); "autologinGroup", configurationMap.value( "autologinGroup" ).toString() );
} }
if ( configurationMap.contains( "sudoersGroup" ) && if ( configurationMap.contains( "sudoersGroup" )
configurationMap.value( "sudoersGroup" ).type() == QVariant::String ) && configurationMap.value( "sudoersGroup" ).type() == QVariant::String )
{ {
Calamares::JobQueue::instance()->globalStorage()->insert( "sudoersGroup", Calamares::JobQueue::instance()->globalStorage()->insert( "sudoersGroup",
configurationMap.value( "sudoersGroup" ).toString() ); configurationMap.value( "sudoersGroup" ).toString() );
} }
if ( configurationMap.contains( "setRootPassword" ) && if ( configurationMap.contains( "setRootPassword" )
configurationMap.value( "setRootPassword" ).type() == QVariant::Bool ) && configurationMap.value( "setRootPassword" ).type() == QVariant::Bool )
{ {
Calamares::JobQueue::instance()->globalStorage()->insert( "setRootPassword", Calamares::JobQueue::instance()->globalStorage()->insert(
configurationMap.value( "setRootPassword" ).toBool() ); "setRootPassword", configurationMap.value( "setRootPassword" ).toBool() );
m_widget->setWriteRootPassword( configurationMap.value( "setRootPassword" ).toBool() ); m_widget->setWriteRootPassword( configurationMap.value( "setRootPassword" ).toBool() );
} }
if ( configurationMap.contains( "doAutologin" ) && if ( configurationMap.contains( "doAutologin" )
configurationMap.value( "doAutologin" ).type() == QVariant::Bool ) && configurationMap.value( "doAutologin" ).type() == QVariant::Bool )
{ {
m_widget->setAutologinDefault( configurationMap.value( "doAutologin" ).toBool() ); m_widget->setAutologinDefault( configurationMap.value( "doAutologin" ).toBool() );
} }
if ( configurationMap.contains( "doReusePassword" ) && if ( configurationMap.contains( "doReusePassword" )
configurationMap.value( "doReusePassword" ).type() == QVariant::Bool ) && configurationMap.value( "doReusePassword" ).type() == QVariant::Bool )
{ {
m_widget->setReusePasswordDefault( configurationMap.value( "doReusePassword" ).toBool() ); m_widget->setReusePasswordDefault( configurationMap.value( "doReusePassword" ).toBool() );
} }
if ( configurationMap.contains( "passwordRequirements" ) && if ( configurationMap.contains( "passwordRequirements" )
configurationMap.value( "passwordRequirements" ).type() == QVariant::Map ) && configurationMap.value( "passwordRequirements" ).type() == QVariant::Map )
{ {
auto pr_checks( configurationMap.value( "passwordRequirements" ).toMap() ); auto pr_checks( configurationMap.value( "passwordRequirements" ).toMap() );
for (decltype(pr_checks)::const_iterator i = pr_checks.constBegin(); for ( decltype( pr_checks )::const_iterator i = pr_checks.constBegin(); i != pr_checks.constEnd(); ++i )
i != pr_checks.constEnd(); ++i)
{ {
m_widget->addPasswordCheck( i.key(), i.value() ); m_widget->addPasswordCheck( i.key(), i.value() );
} }
} }
if ( configurationMap.contains( "allowWeakPasswords" ) && if ( configurationMap.contains( "allowWeakPasswords" )
configurationMap.value( "allowWeakPasswords" ).type() == QVariant::Bool ) && configurationMap.value( "allowWeakPasswords" ).type() == QVariant::Bool )
{ {
m_widget->setPasswordCheckboxVisible( configurationMap.value( "allowWeakPasswords" ).toBool() ); m_widget->setPasswordCheckboxVisible( configurationMap.value( "allowWeakPasswords" ).toBool() );
} }
if ( configurationMap.contains( "doPasswordChecks" ) && if ( configurationMap.contains( "doPasswordChecks" )
configurationMap.value( "doPasswordChecks" ).type() == QVariant::Bool ) && configurationMap.value( "doPasswordChecks" ).type() == QVariant::Bool )
{ {
m_widget->setValidatePasswordDefault( configurationMap.value( "doPasswordChecks" ).toBool() ); m_widget->setValidatePasswordDefault( configurationMap.value( "doPasswordChecks" ).toBool() );
} }
QString shell( QLatin1String( "/bin/bash" ) ); // as if it's not set at all QString shell( QLatin1String( "/bin/bash" ) ); // as if it's not set at all
if ( configurationMap.contains( "userShell" ) ) if ( configurationMap.contains( "userShell" ) )
{
shell = CalamaresUtils::getString( configurationMap, "userShell" ); shell = CalamaresUtils::getString( configurationMap, "userShell" );
}
// Now it might be explicitly set to empty, which is ok // Now it might be explicitly set to empty, which is ok
Calamares::JobQueue::instance()->globalStorage()->insert( "userShell", shell ); Calamares::JobQueue::instance()->globalStorage()->insert( "userShell", shell );
} }