commit
43f9f2e2f4
@ -71,4 +71,7 @@ calamares_add_test(
|
|||||||
SOURCES
|
SOURCES
|
||||||
Tests.cpp
|
Tests.cpp
|
||||||
Config.cpp
|
Config.cpp
|
||||||
|
CheckPWQuality.cpp
|
||||||
|
LIBRARIES
|
||||||
|
${USER_EXTRA_LIB}
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBPWQUALITY
|
#ifdef HAVE_LIBPWQUALITY
|
||||||
#include <pwquality.h>
|
#include <pwquality.h>
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "utils/String.h"
|
#include "utils/String.h"
|
||||||
#include "utils/Variant.h"
|
#include "utils/Variant.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
|
||||||
@ -36,6 +37,22 @@ static const QRegExp HOSTNAME_RX( "^[a-zA-Z0-9][-a-zA-Z0-9_]*$" );
|
|||||||
static constexpr const int HOSTNAME_MIN_LENGTH = 2;
|
static constexpr const int HOSTNAME_MIN_LENGTH = 2;
|
||||||
static constexpr const int HOSTNAME_MAX_LENGTH = 63;
|
static constexpr const int HOSTNAME_MAX_LENGTH = 63;
|
||||||
|
|
||||||
|
const NamedEnumTable< HostNameAction >&
|
||||||
|
hostNameActionNames()
|
||||||
|
{
|
||||||
|
// *INDENT-OFF*
|
||||||
|
// clang-format off
|
||||||
|
static const NamedEnumTable< HostNameAction > names {
|
||||||
|
{ QStringLiteral( "none" ), HostNameAction::None },
|
||||||
|
{ QStringLiteral( "etcfile" ), HostNameAction::EtcHostname },
|
||||||
|
{ QStringLiteral( "hostnamed" ), HostNameAction::SystemdHostname }
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
// *INDENT-ON*
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
Config::Config( QObject* parent )
|
Config::Config( QObject* parent )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
{
|
{
|
||||||
@ -343,6 +360,106 @@ Config::setAutoLogin( bool b )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setReuseUserPasswordForRoot( bool reuse )
|
||||||
|
{
|
||||||
|
if ( reuse != m_reuseUserPasswordForRoot )
|
||||||
|
{
|
||||||
|
m_reuseUserPasswordForRoot = reuse;
|
||||||
|
emit reuseUserPasswordForRootChanged( reuse );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setRequireStrongPasswords( bool strong )
|
||||||
|
{
|
||||||
|
if ( strong != m_requireStrongPasswords )
|
||||||
|
{
|
||||||
|
m_requireStrongPasswords = strong;
|
||||||
|
emit requireStrongPasswordsChanged( strong );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Config::isPasswordAcceptable( const QString& password, QString& message )
|
||||||
|
{
|
||||||
|
bool failureIsFatal = requireStrongPasswords();
|
||||||
|
|
||||||
|
for ( auto pc : m_passwordChecks )
|
||||||
|
{
|
||||||
|
QString s = pc.filter( password );
|
||||||
|
|
||||||
|
if ( !s.isEmpty() )
|
||||||
|
{
|
||||||
|
message = s;
|
||||||
|
return !failureIsFatal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setUserPassword( const QString& s )
|
||||||
|
{
|
||||||
|
m_userPassword = s;
|
||||||
|
// TODO: check new password status
|
||||||
|
emit userPasswordChanged( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setUserPasswordSecondary( const QString& s )
|
||||||
|
{
|
||||||
|
m_userPasswordSecondary = s;
|
||||||
|
// TODO: check new password status
|
||||||
|
emit userPasswordSecondaryChanged( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setRootPassword( const QString& s )
|
||||||
|
{
|
||||||
|
if ( writeRootPassword() )
|
||||||
|
{
|
||||||
|
m_rootPassword = s;
|
||||||
|
// TODO: check new password status
|
||||||
|
emit rootPasswordChanged( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setRootPasswordSecondary( const QString& s )
|
||||||
|
{
|
||||||
|
if ( writeRootPassword() )
|
||||||
|
{
|
||||||
|
m_rootPasswordSecondary = s;
|
||||||
|
// TODO: check new password status
|
||||||
|
emit rootPasswordSecondaryChanged( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Config::rootPassword() const
|
||||||
|
{
|
||||||
|
if ( writeRootPassword() )
|
||||||
|
{
|
||||||
|
if ( reuseUserPasswordForRoot() )
|
||||||
|
return userPassword();
|
||||||
|
return m_rootPassword;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Config::rootPasswordSecondary() const
|
||||||
|
{
|
||||||
|
if ( writeRootPassword() )
|
||||||
|
{
|
||||||
|
if ( reuseUserPasswordForRoot() )
|
||||||
|
return userPasswordSecondary();
|
||||||
|
return m_rootPasswordSecondary;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
STATICTEST void
|
STATICTEST void
|
||||||
setConfigurationDefaultGroups( const QVariantMap& map, QStringList& defaultGroups )
|
setConfigurationDefaultGroups( const QVariantMap& map, QStringList& defaultGroups )
|
||||||
{
|
{
|
||||||
@ -357,6 +474,74 @@ setConfigurationDefaultGroups( const QVariantMap& map, QStringList& defaultGroup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATICTEST HostNameActions
|
||||||
|
getHostNameActions( const QVariantMap& configurationMap )
|
||||||
|
{
|
||||||
|
HostNameAction setHostName = HostNameAction::EtcHostname;
|
||||||
|
QString hostnameActionString = CalamaresUtils::getString( configurationMap, "setHostname" );
|
||||||
|
if ( !hostnameActionString.isEmpty() )
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
setHostName = hostNameActionNames().find( hostnameActionString, ok );
|
||||||
|
if ( !ok )
|
||||||
|
{
|
||||||
|
setHostName = HostNameAction::EtcHostname; // Rather than none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HostNameAction writeHosts = CalamaresUtils::getBool( configurationMap, "writeHostsFile", true )
|
||||||
|
? HostNameAction::WriteEtcHosts
|
||||||
|
: HostNameAction::None;
|
||||||
|
return setHostName | writeHosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Process entries in the passwordRequirements config entry
|
||||||
|
*
|
||||||
|
* Called once for each item in the config entry, which should
|
||||||
|
* be a key-value pair. What makes sense as a value depends on
|
||||||
|
* the key. Supported keys are documented in users.conf.
|
||||||
|
*
|
||||||
|
* @return if the check was added, returns @c true
|
||||||
|
*/
|
||||||
|
STATICTEST bool
|
||||||
|
addPasswordCheck( const QString& key, const QVariant& value, PasswordCheckList& passwordChecks )
|
||||||
|
{
|
||||||
|
if ( key == "minLength" )
|
||||||
|
{
|
||||||
|
add_check_minLength( passwordChecks, value );
|
||||||
|
}
|
||||||
|
else if ( key == "maxLength" )
|
||||||
|
{
|
||||||
|
add_check_maxLength( passwordChecks, value );
|
||||||
|
}
|
||||||
|
else if ( key == "nonempty" )
|
||||||
|
{
|
||||||
|
if ( value.toBool() )
|
||||||
|
{
|
||||||
|
passwordChecks.push_back(
|
||||||
|
PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is empty" ); },
|
||||||
|
[]( const QString& s ) { return !s.isEmpty(); },
|
||||||
|
PasswordCheck::Weight( 1 ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cDebug() << "nonempty check is mentioned but set to false";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef CHECK_PWQUALITY
|
||||||
|
else if ( key == "libpwquality" )
|
||||||
|
{
|
||||||
|
add_check_libpwquality( passwordChecks, value );
|
||||||
|
}
|
||||||
|
#endif // CHECK_PWQUALITY
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cWarning() << "Unknown password-check key" << key;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::setConfigurationMap( const QVariantMap& configurationMap )
|
Config::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
@ -372,9 +557,25 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
setAutologinGroup( CalamaresUtils::getString( configurationMap, "autologinGroup" ) );
|
setAutologinGroup( CalamaresUtils::getString( configurationMap, "autologinGroup" ) );
|
||||||
setSudoersGroup( CalamaresUtils::getString( configurationMap, "sudoersGroup" ) );
|
setSudoersGroup( CalamaresUtils::getString( configurationMap, "sudoersGroup" ) );
|
||||||
|
|
||||||
|
m_hostNameActions = getHostNameActions( configurationMap );
|
||||||
|
|
||||||
setConfigurationDefaultGroups( configurationMap, m_defaultGroups );
|
setConfigurationDefaultGroups( configurationMap, m_defaultGroups );
|
||||||
m_doAutoLogin = CalamaresUtils::getBool( configurationMap, "doAutologin", false );
|
m_doAutoLogin = CalamaresUtils::getBool( configurationMap, "doAutologin", false );
|
||||||
|
|
||||||
m_writeRootPassword = CalamaresUtils::getBool( configurationMap, "setRootPassword", true );
|
m_writeRootPassword = CalamaresUtils::getBool( configurationMap, "setRootPassword", true );
|
||||||
Calamares::JobQueue::instance()->globalStorage()->insert( "setRootPassword", m_writeRootPassword );
|
Calamares::JobQueue::instance()->globalStorage()->insert( "setRootPassword", m_writeRootPassword );
|
||||||
|
|
||||||
|
m_reuseUserPasswordForRoot = CalamaresUtils::getBool( configurationMap, "doReusePassword", false );
|
||||||
|
|
||||||
|
m_permitWeakPasswords = CalamaresUtils::getBool( configurationMap, "allowWeakPasswords", false );
|
||||||
|
m_requireStrongPasswords
|
||||||
|
= !m_permitWeakPasswords || !CalamaresUtils::getBool( configurationMap, "allowWeakPasswordsDefault", false );
|
||||||
|
|
||||||
|
// If the value doesn't exist, or isn't a map, this gives an empty map -- no problem
|
||||||
|
auto pr_checks( configurationMap.value( "passwordRequirements" ).toMap() );
|
||||||
|
for ( decltype( pr_checks )::const_iterator i = pr_checks.constBegin(); i != pr_checks.constEnd(); ++i )
|
||||||
|
{
|
||||||
|
addPasswordCheck( i.key(), i.value(), m_passwordChecks );
|
||||||
|
}
|
||||||
|
std::sort( m_passwordChecks.begin(), m_passwordChecks.end() );
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,25 @@
|
|||||||
#ifndef USERS_CONFIG_H
|
#ifndef USERS_CONFIG_H
|
||||||
#define USERS_CONFIG_H
|
#define USERS_CONFIG_H
|
||||||
|
|
||||||
|
#include "CheckPWQuality.h"
|
||||||
|
|
||||||
|
#include "utils/NamedEnum.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
|
enum HostNameAction
|
||||||
|
{
|
||||||
|
None = 0x0,
|
||||||
|
EtcHostname = 0x1, // Write to /etc/hostname directly
|
||||||
|
SystemdHostname = 0x2, // Set via hostnamed(1)
|
||||||
|
WriteEtcHosts = 0x4 // Write /etc/hosts (127.0.1.1 is this host)
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS( HostNameActions, HostNameAction )
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS( HostNameActions )
|
||||||
|
|
||||||
|
const NamedEnumTable< HostNameAction >& hostNameActionNames();
|
||||||
|
|
||||||
class Config : public QObject
|
class Config : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -41,6 +57,22 @@ class Config : public QObject
|
|||||||
|
|
||||||
Q_PROPERTY( QString hostName READ hostName WRITE setHostName NOTIFY hostNameChanged )
|
Q_PROPERTY( QString hostName READ hostName WRITE setHostName NOTIFY hostNameChanged )
|
||||||
Q_PROPERTY( QString hostNameStatus READ hostNameStatus NOTIFY hostNameStatusChanged )
|
Q_PROPERTY( QString hostNameStatus READ hostNameStatus NOTIFY hostNameStatusChanged )
|
||||||
|
Q_PROPERTY( HostNameActions hostNameActions READ hostNameActions CONSTANT )
|
||||||
|
|
||||||
|
Q_PROPERTY( QString userPassword READ userPassword WRITE setUserPassword NOTIFY userPasswordChanged )
|
||||||
|
Q_PROPERTY( QString userPasswordSecondary READ userPasswordSecondary WRITE setUserPasswordSecondary NOTIFY
|
||||||
|
userPasswordSecondaryChanged )
|
||||||
|
Q_PROPERTY( QString rootPassword READ rootPassword WRITE setRootPassword NOTIFY rootPasswordChanged )
|
||||||
|
Q_PROPERTY( QString rootPasswordSecondary READ rootPasswordSecondary WRITE setRootPasswordSecondary NOTIFY
|
||||||
|
rootPasswordSecondaryChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( bool writeRootPassword READ writeRootPassword CONSTANT )
|
||||||
|
Q_PROPERTY( bool reuseUserPasswordForRoot READ reuseUserPasswordForRoot WRITE setReuseUserPasswordForRoot NOTIFY
|
||||||
|
reuseUserPasswordForRootChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( bool permitWeakPasswords READ permitWeakPasswords CONSTANT )
|
||||||
|
Q_PROPERTY( bool requireStrongPasswords READ requireStrongPasswords WRITE setRequireStrongPasswords NOTIFY
|
||||||
|
requireStrongPasswordsChanged )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Config( QObject* parent = nullptr );
|
Config( QObject* parent = nullptr );
|
||||||
@ -71,14 +103,42 @@ public:
|
|||||||
QString hostName() const { return m_hostName; }
|
QString hostName() const { return m_hostName; }
|
||||||
/// Status message about hostname -- empty for "ok"
|
/// Status message about hostname -- empty for "ok"
|
||||||
QString hostNameStatus() const;
|
QString hostNameStatus() const;
|
||||||
|
/// How to write the hostname
|
||||||
|
HostNameActions hostNameActions() const { return m_hostNameActions; }
|
||||||
|
|
||||||
/// Should the user be automatically logged-in?
|
/// Should the user be automatically logged-in?
|
||||||
bool doAutoLogin() const { return m_doAutoLogin; }
|
bool doAutoLogin() const { return m_doAutoLogin; }
|
||||||
/// Should the root password be written (if false, no password is set and the root account is disabled for login)
|
/// Should the root password be written (if false, no password is set and the root account is disabled for login)
|
||||||
bool writeRootPassword() const { return m_writeRootPassword; }
|
bool writeRootPassword() const { return m_writeRootPassword; }
|
||||||
|
/// Should the user's password be used for root, too? (if root is written at all)
|
||||||
|
bool reuseUserPasswordForRoot() const { return m_reuseUserPasswordForRoot; }
|
||||||
|
/// Show UI to change the "require strong password" setting?
|
||||||
|
bool permitWeakPasswords() const { return m_permitWeakPasswords; }
|
||||||
|
/// Current setting for "require strong password"?
|
||||||
|
bool requireStrongPasswords() const { return m_requireStrongPasswords; }
|
||||||
|
|
||||||
const QStringList& defaultGroups() const { return m_defaultGroups; }
|
const QStringList& defaultGroups() const { return m_defaultGroups; }
|
||||||
|
|
||||||
|
/** @brief Checks if the password is acceptable.
|
||||||
|
*
|
||||||
|
* If all is well, sets @p message to empty and returns @c true.
|
||||||
|
* If there are warnings, but acceptable, sets @p message to something
|
||||||
|
* non-empty and returns @c true. This happens if requireStrongPasswords
|
||||||
|
* is turned off (by config or user).
|
||||||
|
* If the password is not acceptable, sets @p message to something
|
||||||
|
* non-empty and returns @c false.
|
||||||
|
*/
|
||||||
|
bool isPasswordAcceptable( const QString& password, QString& message );
|
||||||
|
|
||||||
|
// The user enters a password (and again in a separate UI element)
|
||||||
|
QString userPassword() const { return m_userPassword; }
|
||||||
|
QString userPasswordSecondary() const { return m_userPasswordSecondary; }
|
||||||
|
// The root password **may** be entered in the UI, or may be suppressed
|
||||||
|
// entirely when writeRootPassword is off, or may be equal to
|
||||||
|
// the user password when reuseUserPasswordForRoot is on.
|
||||||
|
QString rootPassword() const;
|
||||||
|
QString rootPasswordSecondary() const;
|
||||||
|
|
||||||
static const QStringList& forbiddenLoginNames();
|
static const QStringList& forbiddenLoginNames();
|
||||||
static const QStringList& forbiddenHostNames();
|
static const QStringList& forbiddenHostNames();
|
||||||
|
|
||||||
@ -109,6 +169,16 @@ public Q_SLOTS:
|
|||||||
/// Sets the autologin flag
|
/// Sets the autologin flag
|
||||||
void setAutoLogin( bool b );
|
void setAutoLogin( bool b );
|
||||||
|
|
||||||
|
/// Set to true to use the user password, unchanged, for root too
|
||||||
|
void setReuseUserPasswordForRoot( bool reuse );
|
||||||
|
/// Change setting for "require strong password"
|
||||||
|
void setRequireStrongPasswords( bool strong );
|
||||||
|
|
||||||
|
void setUserPassword( const QString& );
|
||||||
|
void setUserPasswordSecondary( const QString& );
|
||||||
|
void setRootPassword( const QString& );
|
||||||
|
void setRootPasswordSecondary( const QString& );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void userShellChanged( const QString& );
|
void userShellChanged( const QString& );
|
||||||
void autologinGroupChanged( const QString& );
|
void autologinGroupChanged( const QString& );
|
||||||
@ -119,6 +189,13 @@ signals:
|
|||||||
void hostNameChanged( const QString& );
|
void hostNameChanged( const QString& );
|
||||||
void hostNameStatusChanged( const QString& );
|
void hostNameStatusChanged( const QString& );
|
||||||
void autoLoginChanged( bool );
|
void autoLoginChanged( bool );
|
||||||
|
void reuseUserPasswordForRootChanged( bool );
|
||||||
|
void requireStrongPasswordsChanged( bool );
|
||||||
|
void userPasswordChanged( const QString& );
|
||||||
|
void userPasswordSecondaryChanged( const QString& );
|
||||||
|
void rootPasswordChanged( const QString& );
|
||||||
|
void rootPasswordSecondaryChanged( const QString& );
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList m_defaultGroups;
|
QStringList m_defaultGroups;
|
||||||
@ -128,11 +205,25 @@ private:
|
|||||||
QString m_fullName;
|
QString m_fullName;
|
||||||
QString m_loginName;
|
QString m_loginName;
|
||||||
QString m_hostName;
|
QString m_hostName;
|
||||||
|
|
||||||
|
QString m_userPassword;
|
||||||
|
QString m_userPasswordSecondary; // enter again to be sure
|
||||||
|
QString m_rootPassword;
|
||||||
|
QString m_rootPasswordSecondary;
|
||||||
|
|
||||||
bool m_doAutoLogin = false;
|
bool m_doAutoLogin = false;
|
||||||
|
|
||||||
bool m_writeRootPassword = true;
|
bool m_writeRootPassword = true;
|
||||||
|
bool m_reuseUserPasswordForRoot = false;
|
||||||
|
|
||||||
|
bool m_permitWeakPasswords = false;
|
||||||
|
bool m_requireStrongPasswords = true;
|
||||||
|
|
||||||
bool m_customLoginName = false;
|
bool m_customLoginName = false;
|
||||||
bool m_customHostName = false;
|
bool m_customHostName = false;
|
||||||
|
|
||||||
|
HostNameActions m_hostNameActions;
|
||||||
|
PasswordCheckList m_passwordChecks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,13 +27,13 @@
|
|||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QtDBus/QDBusConnection>
|
#include <QDBusConnection>
|
||||||
#include <QtDBus/QDBusInterface>
|
#include <QDBusInterface>
|
||||||
#include <QtDBus/QDBusReply>
|
#include <QDBusReply>
|
||||||
|
|
||||||
using WriteMode = CalamaresUtils::System::WriteMode;
|
using WriteMode = CalamaresUtils::System::WriteMode;
|
||||||
|
|
||||||
SetHostNameJob::SetHostNameJob( const QString& hostname, Actions a )
|
SetHostNameJob::SetHostNameJob( const QString& hostname, HostNameActions a )
|
||||||
: Calamares::Job()
|
: Calamares::Job()
|
||||||
, m_hostname( hostname )
|
, m_hostname( hostname )
|
||||||
, m_actions( a )
|
, m_actions( a )
|
||||||
@ -138,7 +138,7 @@ SetHostNameJob::exec()
|
|||||||
return Calamares::JobResult::error( tr( "Internal Error" ) );
|
return Calamares::JobResult::error( tr( "Internal Error" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_actions & Action::EtcHostname )
|
if ( m_actions & HostNameAction::EtcHostname )
|
||||||
{
|
{
|
||||||
if ( !setFileHostname( m_hostname ) )
|
if ( !setFileHostname( m_hostname ) )
|
||||||
{
|
{
|
||||||
@ -147,7 +147,7 @@ SetHostNameJob::exec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_actions & Action::WriteEtcHosts )
|
if ( m_actions & HostNameAction::WriteEtcHosts )
|
||||||
{
|
{
|
||||||
if ( !writeFileEtcHosts( m_hostname ) )
|
if ( !writeFileEtcHosts( m_hostname ) )
|
||||||
{
|
{
|
||||||
@ -156,7 +156,7 @@ SetHostNameJob::exec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_actions & Action::SystemdHostname )
|
if ( m_actions & HostNameAction::SystemdHostname )
|
||||||
{
|
{
|
||||||
// Does its own logging
|
// Does its own logging
|
||||||
setSystemdHostname( m_hostname );
|
setSystemdHostname( m_hostname );
|
||||||
|
@ -21,23 +21,15 @@
|
|||||||
#ifndef SETHOSTNAMEJOB_CPP_H
|
#ifndef SETHOSTNAMEJOB_CPP_H
|
||||||
#define SETHOSTNAMEJOB_CPP_H
|
#define SETHOSTNAMEJOB_CPP_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
#include "Job.h"
|
#include "Job.h"
|
||||||
|
|
||||||
class SetHostNameJob : public Calamares::Job
|
class SetHostNameJob : public Calamares::Job
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum Action
|
SetHostNameJob( const QString& hostname, HostNameActions a );
|
||||||
{
|
|
||||||
None = 0x0,
|
|
||||||
EtcHostname = 0x1, // Write to /etc/hostname directly
|
|
||||||
SystemdHostname = 0x2, // Set via hostnamed(1)
|
|
||||||
WriteEtcHosts = 0x4 // Write /etc/hosts (127.0.1.1 is this host)
|
|
||||||
};
|
|
||||||
Q_DECLARE_FLAGS( Actions, Action )
|
|
||||||
|
|
||||||
|
|
||||||
SetHostNameJob( const QString& hostname, Actions a );
|
|
||||||
QString prettyName() const override;
|
QString prettyName() const override;
|
||||||
QString prettyDescription() const override;
|
QString prettyDescription() const override;
|
||||||
QString prettyStatusMessage() const override;
|
QString prettyStatusMessage() const override;
|
||||||
@ -45,9 +37,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_hostname;
|
const QString m_hostname;
|
||||||
const Actions m_actions;
|
const HostNameActions m_actions;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS( SetHostNameJob::Actions )
|
|
||||||
|
|
||||||
#endif // SETHOSTNAMEJOB_CPP_H
|
#endif // SETHOSTNAMEJOB_CPP_H
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
// Implementation details
|
// Implementation details
|
||||||
extern void setConfigurationDefaultGroups( const QVariantMap& map, QStringList& defaultGroups );
|
extern void setConfigurationDefaultGroups( const QVariantMap& map, QStringList& defaultGroups );
|
||||||
|
extern HostNameActions getHostNameActions( const QVariantMap& configurationMap );
|
||||||
|
extern bool addPasswordCheck( const QString& key, const QVariant& value, PasswordCheckList& passwordChecks );
|
||||||
|
|
||||||
/** @brief Test Config object methods and internals
|
/** @brief Test Config object methods and internals
|
||||||
*
|
*
|
||||||
@ -40,6 +42,9 @@ private Q_SLOTS:
|
|||||||
void initTestCase();
|
void initTestCase();
|
||||||
|
|
||||||
void testDefaultGroups();
|
void testDefaultGroups();
|
||||||
|
void testHostActions_data();
|
||||||
|
void testHostActions();
|
||||||
|
void testPasswordChecks();
|
||||||
};
|
};
|
||||||
|
|
||||||
UserTests::UserTests() {}
|
UserTests::UserTests() {}
|
||||||
@ -105,6 +110,52 @@ UserTests::testDefaultGroups()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserTests::testHostActions_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn< bool >( "set" );
|
||||||
|
QTest::addColumn< QString >( "string" );
|
||||||
|
QTest::addColumn< int >( "result" );
|
||||||
|
|
||||||
|
QTest::newRow( "unset " ) << false << QString() << int( HostNameAction::EtcHostname );
|
||||||
|
QTest::newRow( "empty " ) << true << QString() << int( HostNameAction::EtcHostname );
|
||||||
|
QTest::newRow( "bad " ) << true << QString( "derp" ) << int( HostNameAction::EtcHostname );
|
||||||
|
QTest::newRow( "none " ) << true << QString( "none" ) << int( HostNameAction::None );
|
||||||
|
QTest::newRow( "systemd" ) << true << QString( "Hostnamed" ) << int( HostNameAction::SystemdHostname );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserTests::testHostActions()
|
||||||
|
{
|
||||||
|
QFETCH( bool, set );
|
||||||
|
QFETCH( QString, string );
|
||||||
|
QFETCH( int, result );
|
||||||
|
|
||||||
|
QVariantMap m;
|
||||||
|
if ( set )
|
||||||
|
{
|
||||||
|
m.insert( "setHostname", string );
|
||||||
|
}
|
||||||
|
QCOMPARE( getHostNameActions( m ), HostNameActions( result ) | HostNameAction::WriteEtcHosts ); // write bits default to true
|
||||||
|
m.insert( "writeHostsFile", false );
|
||||||
|
QCOMPARE( getHostNameActions( m ), HostNameActions( result ) );
|
||||||
|
m.insert( "writeHostsFile", true );
|
||||||
|
QCOMPARE( getHostNameActions( m ), HostNameActions( result ) | HostNameAction::WriteEtcHosts );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserTests::testPasswordChecks()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
PasswordCheckList l;
|
||||||
|
QCOMPARE( l.length(), 0 );
|
||||||
|
QVERIFY( !addPasswordCheck( "nonempty", QVariant(false), l ) ); // a silly setting
|
||||||
|
QCOMPARE( l.length(), 0 );
|
||||||
|
QVERIFY( addPasswordCheck( "nonempty", QVariant(true), l ) );
|
||||||
|
QCOMPARE( l.length(), 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN( UserTests )
|
QTEST_GUILESS_MAIN( UserTests )
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ enum class Badness
|
|||||||
|
|
||||||
/** Add an error message and pixmap to a label. */
|
/** Add an error message and pixmap to a label. */
|
||||||
static inline void
|
static inline void
|
||||||
labelError( QLabel* pix, QLabel* label, const QString& message, Badness bad = Badness::Fatal )
|
labelError( QLabel* pix, QLabel* label, const QString& message, Badness bad )
|
||||||
{
|
{
|
||||||
label->setText( message );
|
label->setText( message );
|
||||||
pix->setPixmap( CalamaresUtils::defaultPixmap( ( bad == Badness::Fatal ) ? CalamaresUtils::StatusError
|
pix->setPixmap( CalamaresUtils::defaultPixmap( ( bad == Badness::Fatal ) ? CalamaresUtils::StatusError
|
||||||
@ -88,7 +88,7 @@ labelStatus( QLabel* pix, QLabel* label, const QString& value, const QString& st
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
labelError( pix, label, status );
|
labelError( pix, label, status, Badness::Fatal );
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,6 +105,12 @@ UsersPage::UsersPage( Config* config, QWidget* parent )
|
|||||||
{
|
{
|
||||||
ui->setupUi( this );
|
ui->setupUi( this );
|
||||||
|
|
||||||
|
ui->checkBoxReusePassword->setVisible( m_config->writeRootPassword() );
|
||||||
|
ui->checkBoxReusePassword->setChecked( m_config->reuseUserPasswordForRoot() );
|
||||||
|
|
||||||
|
ui->checkBoxValidatePassword->setVisible( m_config->permitWeakPasswords() );
|
||||||
|
ui->checkBoxValidatePassword->setChecked( m_config->requireStrongPasswords() );
|
||||||
|
|
||||||
// Connect signals and slots
|
// Connect signals and slots
|
||||||
connect( ui->textBoxUserPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged );
|
connect( ui->textBoxUserPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged );
|
||||||
connect( ui->textBoxUserVerifiedPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged );
|
connect( ui->textBoxUserVerifiedPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged );
|
||||||
@ -115,21 +121,7 @@ UsersPage::UsersPage( Config* config, QWidget* parent )
|
|||||||
onRootPasswordTextChanged( ui->textBoxRootPassword->text() );
|
onRootPasswordTextChanged( ui->textBoxRootPassword->text() );
|
||||||
checkReady( isReady() );
|
checkReady( isReady() );
|
||||||
} );
|
} );
|
||||||
connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( const int checked ) {
|
connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, &UsersPage::onReuseUserPasswordChanged );
|
||||||
/* When "reuse" is checked, hide the fields for explicitly
|
|
||||||
* entering the root password. However, if we're going to
|
|
||||||
* disable the root password anyway, hide them all regardless of
|
|
||||||
* the checkbox -- so when writeRoot is false, checked needs
|
|
||||||
* to be true, to hide them all.
|
|
||||||
*/
|
|
||||||
const bool visible = m_config->writeRootPassword() ? !checked : false;
|
|
||||||
ui->labelChooseRootPassword->setVisible( visible );
|
|
||||||
ui->labelRootPassword->setVisible( visible );
|
|
||||||
ui->labelRootPasswordError->setVisible( visible );
|
|
||||||
ui->textBoxRootPassword->setVisible( visible );
|
|
||||||
ui->textBoxVerifiedRootPassword->setVisible( visible );
|
|
||||||
checkReady( isReady() );
|
|
||||||
} );
|
|
||||||
|
|
||||||
connect( ui->textBoxFullName, &QLineEdit::textEdited, config, &Config::setFullName );
|
connect( ui->textBoxFullName, &QLineEdit::textEdited, config, &Config::setFullName );
|
||||||
connect( config, &Config::fullNameChanged, this, &UsersPage::onFullNameTextEdited );
|
connect( config, &Config::fullNameChanged, this, &UsersPage::onFullNameTextEdited );
|
||||||
@ -147,13 +139,25 @@ UsersPage::UsersPage( Config* config, QWidget* parent )
|
|||||||
} );
|
} );
|
||||||
connect( config, &Config::autoLoginChanged, ui->checkBoxDoAutoLogin, &QCheckBox::setChecked );
|
connect( config, &Config::autoLoginChanged, ui->checkBoxDoAutoLogin, &QCheckBox::setChecked );
|
||||||
|
|
||||||
ui->checkBoxReusePassword->setVisible( m_config->writeRootPassword() );
|
if ( m_config->writeRootPassword() )
|
||||||
ui->checkBoxReusePassword->setChecked( true );
|
{
|
||||||
ui->checkBoxValidatePassword->setChecked( true );
|
connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( int checked ) {
|
||||||
|
m_config->setReuseUserPasswordForRoot( checked != Qt::Unchecked );
|
||||||
|
} );
|
||||||
|
connect( config, &Config::reuseUserPasswordForRootChanged, ui->checkBoxReusePassword, &QCheckBox::setChecked );
|
||||||
|
}
|
||||||
|
|
||||||
setPasswordCheckboxVisible( false );
|
if ( m_config->permitWeakPasswords() )
|
||||||
|
{
|
||||||
|
connect( ui->checkBoxValidatePassword, &QCheckBox::stateChanged, this, [this]( int checked ) {
|
||||||
|
m_config->setRequireStrongPasswords( checked != Qt::Unchecked );
|
||||||
|
} );
|
||||||
|
connect( config, &Config::requireStrongPasswordsChanged, ui->checkBoxValidatePassword, &QCheckBox::setChecked );
|
||||||
|
}
|
||||||
|
|
||||||
CALAMARES_RETRANSLATE_SLOT( &UsersPage::retranslate );
|
CALAMARES_RETRANSLATE_SLOT( &UsersPage::retranslate );
|
||||||
|
|
||||||
|
onReuseUserPasswordChanged( m_config->reuseUserPasswordForRoot() );
|
||||||
}
|
}
|
||||||
|
|
||||||
UsersPage::~UsersPage()
|
UsersPage::~UsersPage()
|
||||||
@ -195,32 +199,6 @@ UsersPage::isReady() const
|
|||||||
return readyFields;
|
return readyFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
|
||||||
UsersPage::getRootPassword() const
|
|
||||||
{
|
|
||||||
if ( m_config->writeRootPassword() )
|
|
||||||
{
|
|
||||||
if ( ui->checkBoxReusePassword->isChecked() )
|
|
||||||
{
|
|
||||||
return ui->textBoxUserPassword->text();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ui->textBoxRootPassword->text();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPair< QString, QString >
|
|
||||||
UsersPage::getUserPassword() const
|
|
||||||
{
|
|
||||||
return QPair< QString, QString >( m_config->loginName(), ui->textBoxUserPassword->text() );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
UsersPage::fillGlobalStorage() const
|
UsersPage::fillGlobalStorage() const
|
||||||
{
|
{
|
||||||
@ -274,43 +252,26 @@ UsersPage::checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLab
|
|||||||
{
|
{
|
||||||
if ( pw1 != pw2 )
|
if ( pw1 != pw2 )
|
||||||
{
|
{
|
||||||
labelError( badge, message, tr( "Your passwords do not match!" ) );
|
labelError( badge, message, tr( "Your passwords do not match!" ), Badness::Fatal );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool failureIsFatal = ui->checkBoxValidatePassword->isChecked();
|
QString s;
|
||||||
bool failureFound = false;
|
bool ok = m_config->isPasswordAcceptable( pw1, s );
|
||||||
|
if ( !ok )
|
||||||
if ( m_passwordChecksChanged )
|
|
||||||
{
|
{
|
||||||
std::sort( m_passwordChecks.begin(), m_passwordChecks.end() );
|
labelError( badge, message, s, Badness::Fatal );
|
||||||
m_passwordChecksChanged = false;
|
|
||||||
}
|
}
|
||||||
|
else if ( !s.isEmpty() )
|
||||||
for ( auto pc : m_passwordChecks )
|
|
||||||
{
|
{
|
||||||
QString s = pc.filter( pw1 );
|
labelError( badge, message, s, Badness::Warning );
|
||||||
|
|
||||||
if ( !s.isEmpty() )
|
|
||||||
{
|
|
||||||
labelError( badge, message, s, failureIsFatal ? Badness::Fatal : Badness::Warning );
|
|
||||||
failureFound = true;
|
|
||||||
if ( failureIsFatal )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if ( !failureFound )
|
|
||||||
{
|
{
|
||||||
labelOk( badge, message );
|
labelOk( badge, message );
|
||||||
}
|
}
|
||||||
|
return ok;
|
||||||
// Here, if failureFound is true then we've found **warnings**,
|
|
||||||
// which is ok to continue but the user should know.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,58 +296,24 @@ UsersPage::onRootPasswordTextChanged( const QString& )
|
|||||||
emit checkReady( isReady() );
|
emit checkReady( isReady() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
UsersPage::setPasswordCheckboxVisible( bool visible )
|
UsersPage::onReuseUserPasswordChanged( const int checked )
|
||||||
{
|
{
|
||||||
ui->checkBoxValidatePassword->setVisible( visible );
|
/* When "reuse" is checked, hide the fields for explicitly
|
||||||
}
|
* entering the root password. However, if we're going to
|
||||||
|
* disable the root password anyway, hide them all regardless of
|
||||||
void
|
* the checkbox -- so when writeRoot is false, visible needs
|
||||||
UsersPage::setValidatePasswordDefault( bool checked )
|
* to be false, to hide them all.
|
||||||
{
|
*
|
||||||
ui->checkBoxValidatePassword->setChecked( checked );
|
* In principle this is only connected when writeRootPassword is @c true,
|
||||||
emit checkReady( isReady() );
|
* but it is **always** called at least once in the constructor
|
||||||
}
|
* to set up initial visibility.
|
||||||
|
*/
|
||||||
void
|
const bool visible = m_config->writeRootPassword() ? !checked : false;
|
||||||
UsersPage::setReusePasswordDefault( bool checked )
|
ui->labelChooseRootPassword->setVisible( visible );
|
||||||
{
|
ui->labelRootPassword->setVisible( visible );
|
||||||
ui->checkBoxReusePassword->setChecked( checked );
|
ui->labelRootPasswordError->setVisible( visible );
|
||||||
emit checkReady( isReady() );
|
ui->textBoxRootPassword->setVisible( visible );
|
||||||
}
|
ui->textBoxVerifiedRootPassword->setVisible( visible );
|
||||||
|
checkReady( isReady() );
|
||||||
void
|
|
||||||
UsersPage::addPasswordCheck( const QString& key, const QVariant& value )
|
|
||||||
{
|
|
||||||
m_passwordChecksChanged = true;
|
|
||||||
|
|
||||||
if ( key == "minLength" )
|
|
||||||
{
|
|
||||||
add_check_minLength( m_passwordChecks, value );
|
|
||||||
}
|
|
||||||
else if ( key == "maxLength" )
|
|
||||||
{
|
|
||||||
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
|
|
||||||
else if ( key == "libpwquality" )
|
|
||||||
{
|
|
||||||
add_check_libpwquality( m_passwordChecks, value );
|
|
||||||
}
|
|
||||||
#endif // CHECK_PWQUALITY
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cWarning() << "Unknown password-check key" << key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
#ifndef USERSPAGE_H
|
#ifndef USERSPAGE_H
|
||||||
#define USERSPAGE_H
|
#define USERSPAGE_H
|
||||||
|
|
||||||
#include "CheckPWQuality.h"
|
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class Config;
|
class Config;
|
||||||
@ -50,29 +48,13 @@ public:
|
|||||||
|
|
||||||
void onActivate();
|
void onActivate();
|
||||||
|
|
||||||
void setPasswordCheckboxVisible( bool visible );
|
|
||||||
void setValidatePasswordDefault( bool checked );
|
|
||||||
void setReusePasswordDefault( bool checked );
|
|
||||||
|
|
||||||
/** @brief Process entries in the passwordRequirements config entry
|
|
||||||
*
|
|
||||||
* Called once for each item in the config entry, which should
|
|
||||||
* be a key-value pair. What makes sense as a value depends on
|
|
||||||
* the key. Supported keys are documented in users.conf.
|
|
||||||
*/
|
|
||||||
void addPasswordCheck( const QString& key, const QVariant& value );
|
|
||||||
|
|
||||||
///@brief Root password, depends on settings, may be empty
|
|
||||||
QString getRootPassword() const;
|
|
||||||
///@brief User name and password
|
|
||||||
QPair< QString, QString > getUserPassword() const;
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onFullNameTextEdited( const QString& );
|
void onFullNameTextEdited( const QString& );
|
||||||
void reportLoginNameStatus( const QString& );
|
void reportLoginNameStatus( const QString& );
|
||||||
void reportHostNameStatus( const QString& );
|
void reportHostNameStatus( const QString& );
|
||||||
void onPasswordTextChanged( const QString& );
|
void onPasswordTextChanged( const QString& );
|
||||||
void onRootPasswordTextChanged( const QString& );
|
void onRootPasswordTextChanged( const QString& );
|
||||||
|
void onReuseUserPasswordChanged( const int );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void checkReady( bool );
|
void checkReady( bool );
|
||||||
@ -91,9 +73,6 @@ private:
|
|||||||
Ui::Page_UserSetup* ui;
|
Ui::Page_UserSetup* ui;
|
||||||
Config* m_config;
|
Config* m_config;
|
||||||
|
|
||||||
PasswordCheckList m_passwordChecks;
|
|
||||||
bool m_passwordChecksChanged = false;
|
|
||||||
|
|
||||||
bool m_readyFullName;
|
bool m_readyFullName;
|
||||||
bool m_readyUsername;
|
bool m_readyUsername;
|
||||||
bool m_readyHostname;
|
bool m_readyHostname;
|
||||||
|
@ -34,28 +34,9 @@
|
|||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( UsersViewStepFactory, registerPlugin< UsersViewStep >(); )
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( UsersViewStepFactory, registerPlugin< UsersViewStep >(); )
|
||||||
|
|
||||||
static const NamedEnumTable< SetHostNameJob::Action >&
|
|
||||||
hostnameActions()
|
|
||||||
{
|
|
||||||
using Action = SetHostNameJob::Action;
|
|
||||||
|
|
||||||
// *INDENT-OFF*
|
|
||||||
// clang-format off
|
|
||||||
static const NamedEnumTable< Action > names {
|
|
||||||
{ QStringLiteral( "none" ), Action::None },
|
|
||||||
{ QStringLiteral( "etcfile" ), Action::EtcHostname },
|
|
||||||
{ QStringLiteral( "hostnamed" ), Action::SystemdHostname }
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
// *INDENT-ON*
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
UsersViewStep::UsersViewStep( QObject* parent )
|
UsersViewStep::UsersViewStep( QObject* parent )
|
||||||
: Calamares::ViewStep( parent )
|
: Calamares::ViewStep( parent )
|
||||||
, m_widget( nullptr )
|
, m_widget( nullptr )
|
||||||
, m_actions( SetHostNameJob::Action::None )
|
|
||||||
, m_config( new Config( this ) )
|
, m_config( new Config( this ) )
|
||||||
{
|
{
|
||||||
emit nextStatusChanged( true );
|
emit nextStatusChanged( true );
|
||||||
@ -151,14 +132,14 @@ UsersViewStep::onLeave()
|
|||||||
m_config->doAutoLogin(),
|
m_config->doAutoLogin(),
|
||||||
m_config->defaultGroups() );
|
m_config->defaultGroups() );
|
||||||
|
|
||||||
auto userPW = m_widget->getUserPassword();
|
j = new SetPasswordJob( m_config->loginName(), m_config->userPassword() );
|
||||||
j = new SetPasswordJob( userPW.first, userPW.second );
|
|
||||||
m_jobs.append( Calamares::job_ptr( j ) );
|
m_jobs.append( Calamares::job_ptr( j ) );
|
||||||
|
|
||||||
j = new SetPasswordJob( "root", m_widget->getRootPassword() );
|
j = new SetPasswordJob( "root", m_config->rootPassword() );
|
||||||
m_jobs.append( Calamares::job_ptr( j ) );
|
m_jobs.append( Calamares::job_ptr( j ) );
|
||||||
|
|
||||||
j = new SetHostNameJob( m_config->hostName(), m_actions );
|
// TODO: Config object should create jobs
|
||||||
|
j = new SetHostNameJob( m_config->hostName(), m_config->hostNameActions() );
|
||||||
m_jobs.append( Calamares::job_ptr( j ) );
|
m_jobs.append( Calamares::job_ptr( j ) );
|
||||||
|
|
||||||
m_widget->fillGlobalStorage();
|
m_widget->fillGlobalStorage();
|
||||||
@ -168,42 +149,5 @@ UsersViewStep::onLeave()
|
|||||||
void
|
void
|
||||||
UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
// Create the widget, after all .. as long as writing configuration to the UI is needed
|
|
||||||
(void)this->widget();
|
|
||||||
using CalamaresUtils::getBool;
|
|
||||||
|
|
||||||
m_widget->setReusePasswordDefault( getBool( configurationMap, "doReusePassword", false ) );
|
|
||||||
|
|
||||||
if ( configurationMap.contains( "passwordRequirements" )
|
|
||||||
&& configurationMap.value( "passwordRequirements" ).type() == QVariant::Map )
|
|
||||||
{
|
|
||||||
auto pr_checks( configurationMap.value( "passwordRequirements" ).toMap() );
|
|
||||||
|
|
||||||
for ( decltype( pr_checks )::const_iterator i = pr_checks.constBegin(); i != pr_checks.constEnd(); ++i )
|
|
||||||
{
|
|
||||||
m_widget->addPasswordCheck( i.key(), i.value() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_widget->setPasswordCheckboxVisible( getBool( configurationMap, "allowWeakPasswords", false ) );
|
|
||||||
m_widget->setValidatePasswordDefault( !getBool( configurationMap, "allowWeakPasswordsDefault", false ) );
|
|
||||||
|
|
||||||
using Action = SetHostNameJob::Action;
|
|
||||||
|
|
||||||
QString hostnameActionString = CalamaresUtils::getString( configurationMap, "setHostname" );
|
|
||||||
if ( hostnameActionString.isEmpty() )
|
|
||||||
{
|
|
||||||
hostnameActionString = QStringLiteral( "EtcFile" );
|
|
||||||
}
|
|
||||||
bool ok = false;
|
|
||||||
auto hostnameAction = hostnameActions().find( hostnameActionString, ok );
|
|
||||||
if ( !ok )
|
|
||||||
{
|
|
||||||
hostnameAction = Action::EtcHostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
Action hostsfileAction = getBool( configurationMap, "writeHostsFile", true ) ? Action::WriteEtcHosts : Action::None;
|
|
||||||
m_actions = hostsfileAction | hostnameAction;
|
|
||||||
|
|
||||||
m_config->setConfigurationMap( configurationMap );
|
m_config->setConfigurationMap( configurationMap );
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
#ifndef USERSPAGEPLUGIN_H
|
#ifndef USERSPAGEPLUGIN_H
|
||||||
#define USERSPAGEPLUGIN_H
|
#define USERSPAGEPLUGIN_H
|
||||||
|
|
||||||
#include "SetHostNameJob.h"
|
|
||||||
|
|
||||||
#include "DllMacro.h"
|
#include "DllMacro.h"
|
||||||
#include "utils/PluginFactory.h"
|
#include "utils/PluginFactory.h"
|
||||||
#include "viewpages/ViewStep.h"
|
#include "viewpages/ViewStep.h"
|
||||||
@ -61,8 +59,6 @@ private:
|
|||||||
UsersPage* m_widget;
|
UsersPage* m_widget;
|
||||||
QList< Calamares::job_ptr > m_jobs;
|
QList< Calamares::job_ptr > m_jobs;
|
||||||
|
|
||||||
SetHostNameJob::Actions m_actions;
|
|
||||||
|
|
||||||
Config* m_config;
|
Config* m_config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -138,4 +138,5 @@ setHostname: EtcFile
|
|||||||
|
|
||||||
# Should /etc/hosts be written with a hostname for this machine
|
# Should /etc/hosts be written with a hostname for this machine
|
||||||
# (also adds localhost and some ipv6 standard entries).
|
# (also adds localhost and some ipv6 standard entries).
|
||||||
|
# Defaults to *true*.
|
||||||
writeHostsFile: true
|
writeHostsFile: true
|
||||||
|
Loading…
Reference in New Issue
Block a user