[users] Move hostname validation to Config

main
Adriaan de Groot 5 years ago
parent 40d7d1baac
commit 9018913af5

@ -33,6 +33,10 @@
static const QRegExp USERNAME_RX( "^[a-z_][a-z0-9_-]*[$]?$" );
static constexpr const int USERNAME_MAX_LENGTH = 31;
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_MAX_LENGTH = 63;
Config::Config( QObject* parent )
: QObject( parent )
{
@ -106,15 +110,22 @@ Config::loginNameStatus() const
return QString();
}
QRegExpValidator validateEntireLoginName( USERNAME_RX );
QRegExpValidator validateFirstLetter( QRegExp( "[a-z_].*" ) ); // anchors are implicit in QRegExpValidator
int pos = -1;
if ( m_loginName.length() > USERNAME_MAX_LENGTH )
{
return tr( "Your username is too long." );
}
for ( const QString& badName : forbiddenLoginNames() )
{
if ( 0 == QString::compare( badName, m_loginName, Qt::CaseSensitive ) )
{
return tr( "'%1' is not allowed as username." ).arg( badName );
}
}
QString login( m_loginName ); // make a copy because validate() doesn't take const&
QRegExpValidator validateEntireLoginName( USERNAME_RX );
QRegExpValidator validateFirstLetter( QRegExp( "[a-z_].*" ) ); // anchors are implicit in QRegExpValidator
int pos = -1;
if ( validateFirstLetter.validate( login, pos ) == QValidator::Invalid )
{
return tr( "Your username must start with a lowercase letter or underscore." );
@ -124,14 +135,6 @@ Config::loginNameStatus() const
return tr( "Only lowercase letters, numbers, underscore and hyphen are allowed." );
}
for ( const QString& badName : forbiddenLoginNames() )
{
if ( 0 == QString::compare( badName, m_loginName, Qt::CaseSensitive ) )
{
return tr( "'%1' is not allowed as user name." ).arg( badName );
}
}
return QString();
}
@ -143,7 +146,52 @@ Config::setHostName( const QString& host )
m_customHostName = !host.isEmpty();
m_hostName = host;
emit hostNameChanged( host );
emit hostNameStatusChanged( hostNameStatus() );
}
}
const QStringList&
Config::forbiddenHostNames()
{
static QStringList forbidden { "localhost" };
return forbidden;
}
QString
Config::hostNameStatus() const
{
// An empty hostname is "ok", even if it isn't really
if ( m_hostName.isEmpty() )
{
return QString();
}
if ( m_hostName.length() < HOSTNAME_MIN_LENGTH )
{
return tr( "Your hostname is too short." );
}
if ( m_hostName.length() > HOSTNAME_MAX_LENGTH )
{
return tr( "Your hostname is too long." );
}
for ( const QString& badName : forbiddenHostNames() )
{
if ( 0 == QString::compare( badName, m_hostName, Qt::CaseSensitive ) )
{
return tr( "'%1' is not allowed as hostname." ).arg( badName );
}
}
QString text = m_hostName;
QRegExpValidator val( HOSTNAME_RX );
int pos = -1;
if ( val.validate( text, pos ) == QValidator::Invalid )
{
return tr( "Only letters, numbers, underscore and hyphen are allowed." );
}
return QString();
}
@ -258,6 +306,7 @@ Config::setFullName( const QString& name )
{
m_hostName = hostname;
emit hostNameChanged( hostname );
emit hostNameStatusChanged( hostNameStatus() );
}
}
}

@ -38,6 +38,7 @@ class Config : public QObject
Q_PROPERTY( QString loginNameStatus READ loginNameStatus NOTIFY loginNameStatusChanged )
Q_PROPERTY( QString hostName READ hostName WRITE setHostName NOTIFY hostNameChanged )
Q_PROPERTY( QString hostNameStatus READ hostNameStatus NOTIFY hostNameStatusChanged )
public:
Config( QObject* parent = nullptr );
@ -66,8 +67,11 @@ public:
/// The host name (name for the system)
QString hostName() const { return m_hostName; }
/// Status message about hostname -- empty for "ok"
QString hostNameStatus() const;
static const QStringList& forbiddenLoginNames();
static const QStringList& forbiddenHostNames();
public Q_SLOTS:
/** @brief Sets the user's shell if possible
@ -101,6 +105,7 @@ signals:
void loginNameChanged( const QString& );
void loginNameStatusChanged( const QString& );
void hostNameChanged( const QString& );
void hostNameStatusChanged( const QString& );
private:
QString m_userShell;

@ -46,11 +46,6 @@
#include <QRegExp>
#include <QRegExpValidator>
static const QRegExp HOSTNAME_RX( "^[a-zA-Z0-9][-a-zA-Z0-9_]*$" );
static constexpr const int USERNAME_MAX_LENGTH = 31;
static constexpr const int HOSTNAME_MIN_LENGTH = 2;
static constexpr const int HOSTNAME_MAX_LENGTH = 63;
/** @brief How bad is the error for labelError() ? */
enum class Badness
{
@ -77,6 +72,32 @@ labelOk( QLabel* pix, QLabel* label )
pix->setPixmap( CalamaresUtils::defaultPixmap( CalamaresUtils::Yes, CalamaresUtils::Original, label->size() ) );
}
/** Indicate error, update @p ok based on @p status */
static inline void
labelStatus( QLabel* pix, QLabel* label, const QString& value, const QString& status, bool& ok )
{
if ( status.isEmpty() )
{
if ( value.isEmpty() )
{
// This is different from labelOK() because no checkmark is shown
label->clear();
pix->clear();
ok = false;
}
else
{
labelOk( pix, label );
ok = true;
}
}
else
{
labelError( pix, label, status );
ok = false;
}
}
UsersPage::UsersPage( Config* config, QWidget* parent )
: QWidget( parent )
, ui( new Ui::Page_UserSetup )
@ -124,7 +145,7 @@ UsersPage::UsersPage( Config* config, QWidget* parent )
connect( ui->textBoxHostName, &QLineEdit::textEdited, config, &Config::setHostName );
connect( config, &Config::hostNameChanged, ui->textBoxHostName, &QLineEdit::setText );
connect( config, &Config::hostNameChanged, this, &UsersPage::validateHostnameText );
connect( config, &Config::hostNameStatusChanged, this, &UsersPage::reportHostNameStatus );
connect( ui->textBoxLoginName, &QLineEdit::textEdited, config, &Config::setLoginName );
connect( config, &Config::loginNameChanged, ui->textBoxLoginName, &QLineEdit::setText );
@ -279,64 +300,14 @@ UsersPage::onFullNameTextEdited( const QString& textRef )
void
UsersPage::reportLoginNameStatus( const QString& status )
{
if ( status.isEmpty() )
{
if ( m_config->loginName().isEmpty() )
{
ui->labelUsernameError->clear();
ui->labelUsername->clear();
m_readyUsername = false;
}
else
{
labelOk( ui->labelUsername, ui->labelUsernameError );
m_readyUsername = true;
}
}
else
{
labelError( ui->labelUsername, ui->labelUsernameError, status );
m_readyUsername = false;
}
labelStatus( ui->labelUsername, ui->labelUsernameError, m_config->loginName(), status, m_readyUsername );
emit checkReady( isReady() );
}
void
UsersPage::validateHostnameText( const QString& textRef )
UsersPage::reportHostNameStatus( const QString& status )
{
QString text = textRef;
QRegExpValidator val( HOSTNAME_RX );
int pos = -1;
if ( text.isEmpty() )
{
ui->labelHostnameError->clear();
ui->labelHostname->clear();
m_readyHostname = false;
}
else if ( text.length() < HOSTNAME_MIN_LENGTH )
{
labelError( ui->labelHostname, ui->labelHostnameError, tr( "Your hostname is too short." ) );
m_readyHostname = false;
}
else if ( text.length() > HOSTNAME_MAX_LENGTH )
{
labelError( ui->labelHostname, ui->labelHostnameError, tr( "Your hostname is too long." ) );
m_readyHostname = false;
}
else if ( val.validate( text, pos ) == QValidator::Invalid )
{
labelError( ui->labelHostname,
ui->labelHostnameError,
tr( "Only letters, numbers, underscore and hyphen are allowed." ) );
m_readyHostname = false;
}
else
{
labelOk( ui->labelHostname, ui->labelHostnameError );
m_readyHostname = true;
}
labelStatus( ui->labelHostname, ui->labelHostnameError, m_config->hostName(), status, m_readyHostname );
emit checkReady( isReady() );
}

@ -73,7 +73,7 @@ public:
protected slots:
void onFullNameTextEdited( const QString& );
void reportLoginNameStatus( const QString& );
void validateHostnameText( const QString& );
void reportHostNameStatus( const QString& );
void onPasswordTextChanged( const QString& );
void onRootPasswordTextChanged( const QString& );

Loading…
Cancel
Save