[users] Move login validation to Config object
- add a loginNameStatus which is a QString (empty if things are ok) stating what's wrong with the loginName, if anything.
This commit is contained in:
parent
a564d7a753
commit
40d7d1baac
@ -28,6 +28,10 @@
|
||||
|
||||
#include <QFile>
|
||||
#include <QRegExp>
|
||||
#include <QRegExpValidator>
|
||||
|
||||
static const QRegExp USERNAME_RX( "^[a-z_][a-z0-9_-]*[$]?$" );
|
||||
static constexpr const int USERNAME_MAX_LENGTH = 31;
|
||||
|
||||
Config::Config( QObject* parent )
|
||||
: QObject( parent )
|
||||
@ -49,7 +53,7 @@ Config::setUserShell( const QString& shell )
|
||||
}
|
||||
|
||||
static inline void
|
||||
setGS( const QString& key, const QString& group )
|
||||
insertInGlobalStorage( const QString& key, const QString& group )
|
||||
{
|
||||
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
if ( !gs || group.isEmpty() )
|
||||
@ -62,14 +66,14 @@ setGS( const QString& key, const QString& group )
|
||||
void
|
||||
Config::setAutologinGroup( const QString& group )
|
||||
{
|
||||
setGS( QStringLiteral( "autologinGroup" ), group );
|
||||
insertInGlobalStorage( QStringLiteral( "autologinGroup" ), group );
|
||||
emit autologinGroupChanged( group );
|
||||
}
|
||||
|
||||
void
|
||||
Config::setSudoersGroup( const QString& group )
|
||||
{
|
||||
setGS( QStringLiteral( "sudoersGroup" ), group );
|
||||
insertInGlobalStorage( QStringLiteral( "sudoersGroup" ), group );
|
||||
emit sudoersGroupChanged( group );
|
||||
}
|
||||
|
||||
@ -82,9 +86,55 @@ Config::setLoginName( const QString& login )
|
||||
m_customLoginName = !login.isEmpty();
|
||||
m_loginName = login;
|
||||
emit loginNameChanged( login );
|
||||
emit loginNameStatusChanged( loginNameStatus() );
|
||||
}
|
||||
}
|
||||
|
||||
const QStringList&
|
||||
Config::forbiddenLoginNames()
|
||||
{
|
||||
static QStringList forbidden { "root" };
|
||||
return forbidden;
|
||||
}
|
||||
|
||||
QString
|
||||
Config::loginNameStatus() const
|
||||
{
|
||||
// An empty login is "ok", even if it isn't really
|
||||
if ( m_loginName.isEmpty() )
|
||||
{
|
||||
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." );
|
||||
}
|
||||
QString login( m_loginName ); // make a copy because validate() doesn't take const&
|
||||
if ( validateFirstLetter.validate( login, pos ) == QValidator::Invalid )
|
||||
{
|
||||
return tr( "Your username must start with a lowercase letter or underscore." );
|
||||
}
|
||||
if ( validateEntireLoginName.validate( login, pos ) == QValidator::Invalid )
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
void
|
||||
Config::setHostName( const QString& host )
|
||||
{
|
||||
@ -133,7 +183,6 @@ guessProductName()
|
||||
static QString
|
||||
makeLoginNameSuggestion( const QStringList& parts )
|
||||
{
|
||||
static const QRegExp USERNAME_RX( "^[a-z_][a-z0-9_-]*[$]?$" );
|
||||
if ( parts.isEmpty() || parts.first().isEmpty() )
|
||||
{
|
||||
return QString();
|
||||
@ -199,6 +248,7 @@ Config::setFullName( const QString& name )
|
||||
{
|
||||
m_loginName = login;
|
||||
emit loginNameChanged( login );
|
||||
emit loginNameStatusChanged( loginNameStatus() );
|
||||
}
|
||||
}
|
||||
if ( !m_customHostName )
|
||||
|
@ -35,6 +35,7 @@ class Config : public QObject
|
||||
|
||||
Q_PROPERTY( QString fullName READ fullName WRITE setFullName NOTIFY fullNameChanged )
|
||||
Q_PROPERTY( QString loginName READ loginName WRITE setLoginName NOTIFY loginNameChanged )
|
||||
Q_PROPERTY( QString loginNameStatus READ loginNameStatus NOTIFY loginNameStatusChanged )
|
||||
|
||||
Q_PROPERTY( QString hostName READ hostName WRITE setHostName NOTIFY hostNameChanged )
|
||||
|
||||
@ -60,10 +61,14 @@ public:
|
||||
QString fullName() const { return m_fullName; }
|
||||
/// The login name of the user
|
||||
QString loginName() const { return m_loginName; }
|
||||
/// Status message about login -- empty for "ok"
|
||||
QString loginNameStatus() const;
|
||||
|
||||
/// The host name (name for the system)
|
||||
QString hostName() const { return m_hostName; }
|
||||
|
||||
static const QStringList& forbiddenLoginNames();
|
||||
|
||||
public Q_SLOTS:
|
||||
/** @brief Sets the user's shell if possible
|
||||
*
|
||||
@ -94,6 +99,7 @@ signals:
|
||||
void sudoersGroupChanged( const QString& );
|
||||
void fullNameChanged( const QString& );
|
||||
void loginNameChanged( const QString& );
|
||||
void loginNameStatusChanged( const QString& );
|
||||
void hostNameChanged( const QString& );
|
||||
|
||||
private:
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <QRegExp>
|
||||
#include <QRegExpValidator>
|
||||
|
||||
static const QRegExp USERNAME_RX( "^[a-z_][a-z0-9_-]*[$]?$" );
|
||||
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;
|
||||
@ -129,7 +128,7 @@ UsersPage::UsersPage( Config* config, QWidget* parent )
|
||||
|
||||
connect( ui->textBoxLoginName, &QLineEdit::textEdited, config, &Config::setLoginName );
|
||||
connect( config, &Config::loginNameChanged, ui->textBoxLoginName, &QLineEdit::setText );
|
||||
connect( config, &Config::loginNameChanged, this, &UsersPage::validateUsernameText );
|
||||
connect( config, &Config::loginNameStatusChanged, this, &UsersPage::reportLoginNameStatus );
|
||||
|
||||
setWriteRootPassword( true );
|
||||
ui->checkBoxReusePassword->setChecked( true );
|
||||
@ -277,55 +276,31 @@ UsersPage::onFullNameTextEdited( const QString& textRef )
|
||||
checkReady( isReady() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UsersPage::validateUsernameText( const QString& textRef )
|
||||
UsersPage::reportLoginNameStatus( const QString& status )
|
||||
{
|
||||
QString text( textRef );
|
||||
QRegExpValidator val_whole( USERNAME_RX );
|
||||
QRegExpValidator val_start( QRegExp( "[a-z_].*" ) ); // anchors are implicit in QRegExpValidator
|
||||
int pos = -1;
|
||||
|
||||
if ( text.isEmpty() )
|
||||
if ( status.isEmpty() )
|
||||
{
|
||||
ui->labelUsernameError->clear();
|
||||
ui->labelUsername->clear();
|
||||
m_readyUsername = false;
|
||||
}
|
||||
else if ( text.length() > USERNAME_MAX_LENGTH )
|
||||
{
|
||||
labelError( ui->labelUsername, ui->labelUsernameError, tr( "Your username is too long." ) );
|
||||
m_readyUsername = false;
|
||||
}
|
||||
else if ( val_start.validate( text, pos ) == QValidator::Invalid )
|
||||
{
|
||||
labelError( ui->labelUsername,
|
||||
ui->labelUsernameError,
|
||||
tr( "Your username must start with a lowercase letter or underscore." ) );
|
||||
m_readyUsername = false;
|
||||
}
|
||||
else if ( val_whole.validate( text, pos ) == QValidator::Invalid )
|
||||
{
|
||||
labelError( ui->labelUsername,
|
||||
ui->labelUsernameError,
|
||||
tr( "Only lowercase letters, numbers, underscore and hyphen are allowed." ) );
|
||||
m_readyUsername = false;
|
||||
}
|
||||
else if ( 0 == QString::compare( "root", text, Qt::CaseSensitive ) )
|
||||
{
|
||||
labelError( ui->labelUsername, ui->labelUsernameError, tr( "'root' is not allowed as user name." ) );
|
||||
m_readyUsername = false;
|
||||
if ( m_config->loginName().isEmpty() )
|
||||
{
|
||||
ui->labelUsernameError->clear();
|
||||
ui->labelUsername->clear();
|
||||
m_readyUsername = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
labelOk( ui->labelUsername, ui->labelUsernameError );
|
||||
m_readyUsername = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
labelOk( ui->labelUsername, ui->labelUsernameError );
|
||||
m_readyUsername = true;
|
||||
labelError( ui->labelUsername, ui->labelUsernameError, status );
|
||||
m_readyUsername = false;
|
||||
}
|
||||
|
||||
emit checkReady( isReady() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UsersPage::validateHostnameText( const QString& textRef )
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
|
||||
protected slots:
|
||||
void onFullNameTextEdited( const QString& );
|
||||
void validateUsernameText( const QString& );
|
||||
void reportLoginNameStatus( const QString& );
|
||||
void validateHostnameText( const QString& );
|
||||
void onPasswordTextChanged( const QString& );
|
||||
void onRootPasswordTextChanged( const QString& );
|
||||
|
Loading…
Reference in New Issue
Block a user