From 1513934a57f68db1dd964ae23a4bc33022762d86 Mon Sep 17 00:00:00 2001 From: bill-auger Date: Wed, 28 Aug 2019 11:14:00 -0400 Subject: [PATCH 01/22] add checkbox to disable password validations --- src/modules/users/UsersPage.cpp | 68 ++++++++++++++++++++--------- src/modules/users/UsersPage.h | 2 + src/modules/users/UsersViewStep.cpp | 12 +++++ src/modules/users/page_usersetup.ui | 7 +++ src/modules/users/users.conf | 13 +++++- 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 62292b76c..82568f81a 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -88,6 +88,13 @@ UsersPage::UsersPage( QWidget* parent ) this, &UsersPage::onRootPasswordTextChanged ); connect( ui->textBoxVerifiedRootPassword, &QLineEdit::textChanged, this, &UsersPage::onRootPasswordTextChanged ); + connect( ui->checkBoxValidatePassword, &QCheckBox::stateChanged, + this, [this]( int checked ) + { + onPasswordTextChanged( ui->textBoxUserPassword->text() ); + onRootPasswordTextChanged( ui->textBoxRootPassword->text() ); + checkReady( isReady() ); + } ); connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( int checked ) { @@ -105,6 +112,8 @@ UsersPage::UsersPage( QWidget* parent ) setWriteRootPassword( true ); ui->checkBoxReusePassword->setChecked( true ); + ui->checkBoxValidatePassword->setChecked( true ); + ui->checkBoxValidatePassword->setVisible( false ); // Don't expand the explanations to "stupid wide", but keep them vaguely as-wide-as // the things they are explaining. @@ -387,6 +396,7 @@ UsersPage::onPasswordTextChanged( const QString& ) { QString pw1 = ui->textBoxUserPassword->text(); QString pw2 = ui->textBoxUserVerifiedPassword->text(); + m_readyPassword = true; // TODO: 3.3: remove empty-check and leave it to passwordRequirements if ( pw1.isEmpty() && pw2.isEmpty() ) @@ -403,23 +413,24 @@ UsersPage::onPasswordTextChanged( const QString& ) } else { - bool ok = true; - for ( auto pc : m_passwordChecks ) + if ( ui->checkBoxValidatePassword->isChecked() ) { - QString s = pc.filter( pw1 ); - if ( !s.isEmpty() ) + for ( auto pc : m_passwordChecks ) { - labelError( ui->labelUserPassword, ui->labelUserPasswordError, s ); - ok = false; - m_readyPassword = false; - break; + QString s = pc.filter( pw1 ); + + if ( !s.isEmpty() ) + { + labelError( ui->labelUserPassword, ui->labelUserPasswordError, s ); + m_readyPassword = false; + break; + } } } - if ( ok ) + if ( m_readyPassword ) { labelOk( ui->labelUserPassword, ui->labelUserPasswordError ); - m_readyPassword = true; } } @@ -431,6 +442,7 @@ UsersPage::onRootPasswordTextChanged( const QString& ) { QString pw1 = ui->textBoxRootPassword->text(); QString pw2 = ui->textBoxVerifiedRootPassword->text(); + m_readyRootPassword = true; // TODO: 3.3: remove empty-check and leave it to passwordRequirements if ( pw1.isEmpty() && pw2.isEmpty() ) @@ -447,23 +459,24 @@ UsersPage::onRootPasswordTextChanged( const QString& ) } else { - bool ok = true; - for ( auto pc : m_passwordChecks ) + if ( ui->checkBoxValidatePassword->isChecked() ) { - QString s = pc.filter( pw1 ); - if ( !s.isEmpty() ) + for ( auto pc : m_passwordChecks ) { - labelError( ui->labelRootPassword, ui->labelRootPasswordError, s ); - ok = false; - m_readyRootPassword = false; - break; + QString s = pc.filter( pw1 ); + + if ( !s.isEmpty() ) + { + labelError( ui->labelRootPassword, ui->labelRootPasswordError, s ); + m_readyRootPassword = false; + break; + } } } - if ( ok ) + if ( m_readyRootPassword ) { labelOk( ui->labelRootPassword, ui->labelRootPasswordError ); - m_readyRootPassword = true; } } @@ -471,6 +484,19 @@ UsersPage::onRootPasswordTextChanged( const QString& ) } +void +UsersPage::setPasswordCheckboxVisible( bool visible ) +{ + ui->checkBoxValidatePassword->setVisible( visible ); +} + +void +UsersPage::setValidatePasswordDefault( bool checked ) +{ + ui->checkBoxValidatePassword->setChecked( checked ); + emit checkReady( isReady() ); +} + void UsersPage::setAutologinDefault( bool checked ) { @@ -501,7 +527,7 @@ UsersPage::addPasswordCheck( const QString& key, const QVariant& value ) { add_check_libpwquality( m_passwordChecks, value ); } -#endif +#endif // CHECK_PWQUALITY else cWarning() << "Unknown password-check key" << key; } diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index ac1e1f9db..2dbe7aeda 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -48,6 +48,8 @@ public: void onActivate(); void setWriteRootPassword( bool show ); + void setPasswordCheckboxVisible( bool visible ); + void setValidatePasswordDefault( bool checked ); void setAutologinDefault( bool checked ); void setReusePasswordDefault( bool checked ); diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 4582a9e85..676cb7236 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -173,6 +173,18 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } } + if ( configurationMap.contains( "allowWeakPasswords" ) && + configurationMap.value( "allowWeakPasswords" ).type() == QVariant::Bool ) + { + m_widget->setPasswordCheckboxVisible( configurationMap.value( "allowWeakPasswords" ).toBool() ); + } + + if ( configurationMap.contains( "doPasswordChecks" ) && + configurationMap.value( "doPasswordChecks" ).type() == QVariant::Bool ) + { + m_widget->setValidatePasswordDefault( configurationMap.value( "doPasswordChecks" ).toBool() ); + } + QString shell( QLatin1Literal( "/bin/bash" ) ); // as if it's not set at all if ( configurationMap.contains( "userShell" ) ) shell = CalamaresUtils::getString( configurationMap, "userShell" ); diff --git a/src/modules/users/page_usersetup.ui b/src/modules/users/page_usersetup.ui index c93912c01..ae74255c2 100644 --- a/src/modules/users/page_usersetup.ui +++ b/src/modules/users/page_usersetup.ui @@ -460,6 +460,13 @@ + + + + Require strong passwords. + + + diff --git a/src/modules/users/users.conf b/src/modules/users/users.conf index 0c40faeff..0942e6b5d 100644 --- a/src/modules/users/users.conf +++ b/src/modules/users/users.conf @@ -28,7 +28,7 @@ defaultGroups: # Disable when your Distribution does not require such a group. autologinGroup: autologin # You can control the initial state for the 'autologin checkbox' in UsersViewStep here. -# Possible values are: true to enable or false to disable the checkbox by default +# Possible values are: true to enable or false to disable the checkbox by default. doAutologin: true # When set to a non-empty string, Calamares creates a sudoers file for the user. @@ -68,12 +68,23 @@ doReusePassword: true # # (additional checks may be implemented in CheckPWQuality.cpp and # wired into UsersPage.cpp) +# +# To disable specific password validations, +# comment out the relevant 'passwordRequirements' keys below. +# To disable all password validations, +# set both 'allowWeakPasswords' and 'doPasswordChecks' to false. passwordRequirements: minLength: -1 # Password at least this many characters maxLength: -1 # Password at most this many characters libpwquality: - minlen=0 - minclass=0 +# You can control the visibility of the 'strong passwords' checkbox in UsersViewStep here. +# Possible values are: true to show or false to hide the checkbox. +allowWeakPasswords: true +# You can control the initial state for the 'strong passwords' checkbox in UsersViewStep here. +# Possible values are: true to enable or false to disable the checkbox by default. +doPasswordChecks: true # Shell to be used for the regular user of the target system. # There are three possible kinds of settings: From eb90757063fda85ebf7106c9cdf88a75995f493b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 21 Oct 2019 17:21:33 +0200 Subject: [PATCH 02/22] [users] Apply coding style (lots of churn) --- src/modules/users/CheckPWQuality.cpp | 178 +++++++++++++++------------ src/modules/users/CheckPWQuality.h | 27 ++-- src/modules/users/CreateUserJob.cpp | 49 ++++---- src/modules/users/CreateUserJob.h | 5 +- src/modules/users/PasswordTests.cpp | 10 +- src/modules/users/SetHostNameJob.cpp | 28 +++-- src/modules/users/SetHostNameJob.h | 3 +- src/modules/users/SetPasswordJob.cpp | 61 ++++----- src/modules/users/SetPasswordJob.h | 5 +- src/modules/users/UsersPage.cpp | 116 ++++++++--------- src/modules/users/UsersPage.h | 2 +- src/modules/users/UsersViewStep.cpp | 63 +++++----- src/modules/users/UsersViewStep.h | 2 +- 13 files changed, 272 insertions(+), 277 deletions(-) diff --git a/src/modules/users/CheckPWQuality.cpp b/src/modules/users/CheckPWQuality.cpp index 7fa13f124..3728c5a92 100644 --- a/src/modules/users/CheckPWQuality.cpp +++ b/src/modules/users/CheckPWQuality.cpp @@ -32,12 +32,12 @@ PasswordCheck::PasswordCheck() : m_message() - , m_accept( []( const QString& ){ return true; } ) + , m_accept( []( const QString& ) { return true; } ) { } PasswordCheck::PasswordCheck( const QString& m, AcceptFunc a ) - : m_message( [m](){ return m; } ) + : m_message( [m]() { return m; } ) , m_accept( a ) { } @@ -52,21 +52,14 @@ DEFINE_CHECK_FUNC( minLength ) { int minLength = -1; if ( value.canConvert( QVariant::Int ) ) + { minLength = value.toInt(); + } if ( minLength > 0 ) { cDebug() << Logger::SubEntry << "minLength set to" << minLength; - checks.push_back( - PasswordCheck( - []() - { - return QCoreApplication::translate( "PWQ", "Password is too short" ); - }, - [minLength]( const QString& s ) - { - return s.length() >= minLength; - } - ) ); + checks.push_back( PasswordCheck( []() { 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; if ( value.canConvert( QVariant::Int ) ) + { maxLength = value.toInt(); + } if ( maxLength > 0 ) { cDebug() << Logger::SubEntry << "maxLength set to" << maxLength; - checks.push_back( - PasswordCheck( - []() - { - return QCoreApplication::translate("PWQ", "Password is too long" ); - }, - [maxLength]( const QString& s ) - { - return s.length() <= maxLength; - } - ) ); + checks.push_back( PasswordCheck( []() { 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 -static inline long mungeLong( void* p ) +static inline long +mungeLong( void* p ) { - return static_cast( reinterpret_cast( p ) ); + return static_cast< long >( reinterpret_cast< intptr_t >( p ) ); } /// @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( p ); + return reinterpret_cast< const char* >( p ); } /** @@ -128,16 +116,10 @@ public: { } - ~PWSettingsHolder() - { - pwquality_free_settings( m_settings ); - } + ~PWSettingsHolder() { pwquality_free_settings( m_settings ); } /// Sets an option via the configuration string @p v, = style. - int set( const QString& v ) - { - return pwquality_set_option( m_settings, v.toUtf8().constData() ); - } + int set( const QString& v ) { return pwquality_set_option( m_settings, v.toUtf8().constData() ); } /// Checks the given password @p pwd against the current configuration int check( const QString& pwd ) @@ -148,10 +130,7 @@ public: return r; } - bool hasExplanation() const - { - return m_rv < 0; - } + bool hasExplanation() const { return m_rv < 0; } /* This is roughly the same as the function pwquality_strerror, * only with QStrings instead, and using the Qt translation scheme. @@ -164,16 +143,21 @@ public: m_auxerror = nullptr; if ( m_rv >= arbitrary_minimum_strength ) + { return QString(); + } if ( m_rv >= 0 ) - return QCoreApplication::translate( "PWQ", "Password is too weak" ); + { + return QCoreApplication::translate( "PWQ", "Password is too weak" ); + } switch ( m_rv ) { case PWQ_ERROR_MEM_ALLOC: 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 ); return s; } @@ -189,58 +173,94 @@ public: case PWQ_ERROR_USER_CHECK: return QCoreApplication::translate( "PWQ", "The password contains the user name in some form" ); 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: return QCoreApplication::translate( "PWQ", "The password contains forbidden words in some form" ); case PWQ_ERROR_MIN_DIGITS: 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" ); case PWQ_ERROR_MIN_UPPERS: 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" ); case PWQ_ERROR_MIN_LOWERS: 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" ); case PWQ_ERROR_MIN_OTHERS: 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" ); case PWQ_ERROR_MIN_LENGTH: 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" ); case PWQ_ERROR_ROTATED: return QCoreApplication::translate( "PWQ", "The password is just rotated old one" ); case PWQ_ERROR_MIN_CLASSES: 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" ); case PWQ_ERROR_MAX_CONSECUTIVE: 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" ); case PWQ_ERROR_MAX_CLASS_REPEAT: 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: 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: return QCoreApplication::translate( "PWQ", "No password supplied" ); case PWQ_ERROR_RNG: return QCoreApplication::translate( "PWQ", "Cannot obtain random numbers from the RNG device" ); 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: if ( auxerror ) { /* 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" ); case PWQ_ERROR_UNKNOWN_SETTING: @@ -254,7 +274,8 @@ public: case PWQ_ERROR_INTEGER: 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 ); return s; } @@ -262,7 +283,8 @@ public: case PWQ_ERROR_NON_INT_SETTING: 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 ); return s; } @@ -270,7 +292,8 @@ public: case PWQ_ERROR_NON_STR_SETTING: 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 ); return s; } @@ -290,7 +313,7 @@ private: pwquality_settings_t* m_settings; int m_rv; void* m_auxerror; -} ; +}; DEFINE_CHECK_FUNC( libpwquality ) { @@ -302,7 +325,7 @@ DEFINE_CHECK_FUNC( libpwquality ) QVariantList l = value.toList(); unsigned int requirement_count = 0; - auto settings = std::make_shared(); + auto settings = std::make_shared< PWSettingsHolder >(); for ( const auto& v : l ) { if ( v.type() == QVariant::String ) @@ -310,7 +333,9 @@ DEFINE_CHECK_FUNC( libpwquality ) QString option = v.toString(); int r = settings->set( option ); if ( r ) + { cWarning() << "unrecognized libpwquality setting" << option; + } else { cDebug() << Logger::SubEntry << "libpwquality setting" << option; @@ -318,28 +343,27 @@ DEFINE_CHECK_FUNC( libpwquality ) } } else + { cWarning() << "unrecognized libpwquality setting" << v; + } } /* Something actually added? */ if ( requirement_count ) { - checks.push_back( - PasswordCheck( - [settings]() - { - return settings->explanation(); - }, - [settings]( const QString& s ) - { - int r = settings->check( s ); - if ( r < 0 ) - cWarning() << "libpwquality error" << r; - else if ( r < settings->arbitrary_minimum_strength ) - cDebug() << "Password strength" << r << "too low"; - return r >= settings->arbitrary_minimum_strength; - } - ) ); + checks.push_back( PasswordCheck( [settings]() { return settings->explanation(); }, + [settings]( const QString& s ) { + int r = settings->check( s ); + if ( r < 0 ) + { + cWarning() << "libpwquality error" << r; + } + else if ( r < settings->arbitrary_minimum_strength ) + { + cDebug() << "Password strength" << r << "too low"; + } + return r >= settings->arbitrary_minimum_strength; + } ) ); } } #endif diff --git a/src/modules/users/CheckPWQuality.h b/src/modules/users/CheckPWQuality.h index 07760c75b..046f31496 100644 --- a/src/modules/users/CheckPWQuality.h +++ b/src/modules/users/CheckPWQuality.h @@ -35,8 +35,8 @@ class PasswordCheck { public: /** Return true if the string is acceptable. */ - using AcceptFunc = std::function; - using MessageFunc = std::function; + using AcceptFunc = std::function< bool( const QString& ) >; + using MessageFunc = std::function< QString() >; /** Generate a @p message if @p filter returns true */ PasswordCheck( MessageFunc message, AcceptFunc filter ); @@ -50,17 +50,14 @@ public: * according to this filter. Returns a message describing * what is wrong if not. */ - QString filter( const QString& s ) const - { - return m_accept( s ) ? QString() : m_message(); - } + QString filter( const QString& s ) const { return m_accept( s ) ? QString() : m_message(); } private: MessageFunc m_message; AcceptFunc m_accept; -} ; +}; -using PasswordCheckList = QVector; +using PasswordCheckList = QVector< PasswordCheck >; /* Each of these functions adds a check (if possible) to the list * of checks; they use the configuration value(s) from the @@ -68,16 +65,14 @@ using PasswordCheckList = QVector; * may skip adding a check, and do nothing (it should log * an error, though). */ -#define _xDEFINE_CHECK_FUNC(x) \ - add_check_##x( PasswordCheckList& checks, const QVariant& value ) -#define DEFINE_CHECK_FUNC(x) void _xDEFINE_CHECK_FUNC(x) -#define DECLARE_CHECK_FUNC(x) void _xDEFINE_CHECK_FUNC(x); +#define _xDEFINE_CHECK_FUNC( x ) add_check_##x( PasswordCheckList& checks, const QVariant& value ) +#define DEFINE_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(maxLength) +DECLARE_CHECK_FUNC( minLength ) +DECLARE_CHECK_FUNC( maxLength ) #ifdef HAVE_LIBPWQUALITY -DECLARE_CHECK_FUNC(libpwquality) +DECLARE_CHECK_FUNC( libpwquality ) #endif #endif - diff --git a/src/modules/users/CreateUserJob.cpp b/src/modules/users/CreateUserJob.cpp index 788ba0195..b107fb0bb 100644 --- a/src/modules/users/CreateUserJob.cpp +++ b/src/modules/users/CreateUserJob.cpp @@ -19,10 +19,10 @@ #include -#include "JobQueue.h" #include "GlobalStorage.h" -#include "utils/Logger.h" +#include "JobQueue.h" #include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" #include #include @@ -72,17 +72,20 @@ CreateUserJob::exec() Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); QDir destDir( gs->value( "rootMountPoint" ).toString() ); - if ( gs->contains( "sudoersGroup" ) && - !gs->value( "sudoersGroup" ).toString().isEmpty() ) + if ( gs->contains( "sudoersGroup" ) && !gs->value( "sudoersGroup" ).toString().isEmpty() ) { QFileInfo sudoersFi( destDir.absoluteFilePath( "etc/sudoers.d/10-installer" ) ); if ( !sudoersFi.absoluteDir().exists() ) + { return Calamares::JobResult::error( tr( "Sudoers dir is not writable." ) ); + } 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." ) ); + } QString sudoersGroup = gs->value( "sudoersGroup" ).toString(); @@ -96,11 +99,12 @@ CreateUserJob::exec() QFileInfo groupsFi( destDir.absoluteFilePath( "etc/group" ) ); QFile groupsFile( groupsFi.absoluteFilePath() ); if ( !groupsFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { return Calamares::JobResult::error( tr( "Cannot open groups file for reading." ) ); + } QString groupsData = QString::fromLocal8Bit( groupsFile.readAll() ); QStringList groupsLines = groupsData.split( '\n' ); - for ( QStringList::iterator it = groupsLines.begin(); - it != groupsLines.end(); ++it ) + for ( QStringList::iterator it = groupsLines.begin(); it != groupsLines.end(); ++it ) { int indexOfFirstToDrop = it->indexOf( ':' ); it->truncate( indexOfFirstToDrop ); @@ -108,15 +112,13 @@ CreateUserJob::exec() foreach ( const QString& group, m_defaultGroups ) if ( !groupsLines.contains( group ) ) - CalamaresUtils::System::instance()-> - targetEnvCall( { "groupadd", group } ); + CalamaresUtils::System::instance()->targetEnvCall( { "groupadd", group } ); QString defaultGroups = m_defaultGroups.join( ',' ); if ( m_autologin ) { QString autologinGroup; - if ( gs->contains( "autologinGroup" ) && - !gs->value( "autologinGroup" ).toString().isEmpty() ) + if ( gs->contains( "autologinGroup" ) && !gs->value( "autologinGroup" ).toString().isEmpty() ) { autologinGroup = gs->value( "autologinGroup" ).toString(); CalamaresUtils::System::instance()->targetEnvCall( { "groupadd", autologinGroup } ); @@ -131,26 +133,20 @@ CreateUserJob::exec() QDir existingHome( destDir.absolutePath() + shellFriendlyHome ); if ( existingHome.exists() ) { - QString backupDirName = "dotfiles_backup_" + - QDateTime::currentDateTime() - .toString( "yyyy-MM-dd_HH-mm-ss" ); + QString backupDirName = "dotfiles_backup_" + QDateTime::currentDateTime().toString( "yyyy-MM-dd_HH-mm-ss" ); existingHome.mkdir( backupDirName ); - CalamaresUtils::System::instance()-> - targetEnvCall( { "sh", - "-c", - "mv -f " + - shellFriendlyHome + "/.* " + - shellFriendlyHome + "/" + - backupDirName - } ); + CalamaresUtils::System::instance()->targetEnvCall( + { "sh", "-c", "mv -f " + shellFriendlyHome + "/.* " + shellFriendlyHome + "/" + backupDirName } ); } } - QStringList useradd{ "useradd", "-m", "-U" }; + QStringList useradd { "useradd", "-m", "-U" }; QString shell = gs->value( "userShell" ).toString(); if ( !shell.isEmpty() ) + { useradd << "-s" << shell; + } useradd << "-c" << m_fullName; useradd << m_userName; @@ -161,8 +157,8 @@ CreateUserJob::exec() return commandResult.explainProcess( useradd, std::chrono::seconds( 10 ) /* bogus timeout */ ); } - commandResult = CalamaresUtils::System::instance()->targetEnvCommand( - { "usermod", "-aG", defaultGroups, m_userName } ); + commandResult + = CalamaresUtils::System::instance()->targetEnvCommand( { "usermod", "-aG", defaultGroups, m_userName } ); if ( 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 homeDir = QString( "/home/%1" ).arg( m_userName ); - commandResult = CalamaresUtils::System::instance()->targetEnvCommand( - { "chown", "-R", userGroup, homeDir } ); + commandResult = CalamaresUtils::System::instance()->targetEnvCommand( { "chown", "-R", userGroup, homeDir } ); if ( commandResult.getExitCode() ) { cError() << "chown failed" << commandResult.getExitCode(); diff --git a/src/modules/users/CreateUserJob.h b/src/modules/users/CreateUserJob.h index d3459fc8a..98d7c001e 100644 --- a/src/modules/users/CreateUserJob.h +++ b/src/modules/users/CreateUserJob.h @@ -27,10 +27,7 @@ class CreateUserJob : public Calamares::Job { Q_OBJECT public: - CreateUserJob( const QString& userName, - const QString& fullName, - bool autologin, - const QStringList& defaultGroups ); + CreateUserJob( const QString& userName, const QString& fullName, bool autologin, const QStringList& defaultGroups ); QString prettyName() const override; QString prettyDescription() const override; QString prettyStatusMessage() const override; diff --git a/src/modules/users/PasswordTests.cpp b/src/modules/users/PasswordTests.cpp index d4526351a..0c1b4bffc 100644 --- a/src/modules/users/PasswordTests.cpp +++ b/src/modules/users/PasswordTests.cpp @@ -24,13 +24,9 @@ QTEST_GUILESS_MAIN( PasswordTests ) -PasswordTests::PasswordTests() -{ -} +PasswordTests::PasswordTests() {} -PasswordTests::~PasswordTests() -{ -} +PasswordTests::~PasswordTests() {} void PasswordTests::initTestCase() @@ -41,7 +37,7 @@ void PasswordTests::testSalt() { QString s = SetPasswordJob::make_salt( 8 ); - QCOMPARE( s.length(), 4 + 8 ); // 8 salt chars, plus $6$, plus trailing $ + QCOMPARE( s.length(), 4 + 8 ); // 8 salt chars, plus $6$, plus trailing $ QVERIFY( s.startsWith( "$6$" ) ); QVERIFY( s.endsWith( '$' ) ); qDebug() << "Obtained salt" << s; diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index 62b1c61a7..b03d7a200 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -21,11 +21,11 @@ #include "SetHostNameJob.h" #include "GlobalStorage.h" -#include "utils/Logger.h" #include "JobQueue.h" +#include "utils/Logger.h" -#include #include +#include SetHostNameJob::SetHostNameJob( const QString& hostname ) : 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 ); } @@ -52,7 +53,8 @@ SetHostNameJob::prettyStatusMessage() const return tr( "Setting hostname %1." ).arg( m_hostname ); } -Calamares::JobResult SetHostNameJob::exec() +Calamares::JobResult +SetHostNameJob::exec() { 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 QTextStream hostsfileout( &hostsfile ); // ipv4 support - hostsfileout << "127.0.0.1" << "\t" << "localhost" << "\n"; - hostsfileout << "127.0.1.1" << "\t" << m_hostname << "\n"; + hostsfileout << "127.0.0.1" + << "\t" + << "localhost" + << "\n"; + hostsfileout << "127.0.1.1" + << "\t" << m_hostname << "\n"; // ipv6 support - hostsfileout << "::1" << "\t" << "localhost ip6-localhost ip6-loopback" << "\n"; - hostsfileout << "ff02::1 ip6-allnodes" << "\n" << "ff02::2 ip6-allrouters" << "\n"; + hostsfileout << "::1" + << "\t" + << "localhost ip6-localhost ip6-loopback" + << "\n"; + hostsfileout << "ff02::1 ip6-allnodes" + << "\n" + << "ff02::2 ip6-allrouters" + << "\n"; hostsfile.close(); return Calamares::JobResult::ok(); diff --git a/src/modules/users/SetHostNameJob.h b/src/modules/users/SetHostNameJob.h index 11e296fce..ca2481dd4 100644 --- a/src/modules/users/SetHostNameJob.h +++ b/src/modules/users/SetHostNameJob.h @@ -31,9 +31,10 @@ public: QString prettyDescription() const override; QString prettyStatusMessage() const override; Calamares::JobResult exec() override; + private: const QString m_hostname; }; -#endif // SETHOSTNAMEJOB_CPP_H +#endif // SETHOSTNAMEJOB_CPP_H diff --git a/src/modules/users/SetPasswordJob.cpp b/src/modules/users/SetPasswordJob.cpp index 9c560106d..325d24fe3 100644 --- a/src/modules/users/SetPasswordJob.cpp +++ b/src/modules/users/SetPasswordJob.cpp @@ -19,10 +19,10 @@ #include -#include "JobQueue.h" #include "GlobalStorage.h" -#include "utils/Logger.h" +#include "JobQueue.h" #include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" #include @@ -58,29 +58,27 @@ SetPasswordJob::prettyStatusMessage() const /// Returns a modular hashing salt for method 6 (SHA512) with a 16 character random salt. QString -SetPasswordJob::make_salt(int length) +SetPasswordJob::make_salt( int length ) { - Q_ASSERT(length >= 8); - Q_ASSERT(length <= 128); + Q_ASSERT( length >= 8 ); + Q_ASSERT( length <= 128 ); - static const char salt_chars[] = { - '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', - 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + static const char salt_chars[] = { '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', + 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', '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::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; - std::mt19937_64 twister(seed); + std::seed_seq seed { r(), r(), r(), r(), r(), r(), r(), r() }; + std::mt19937_64 twister( seed ); std::uint64_t next; int current_length = 0; QString salt_string; - salt_string.reserve(length + 10); + salt_string.reserve( length + 10 ); while ( current_length < length ) { @@ -89,11 +87,13 @@ SetPasswordJob::make_salt(int length) // to a single salt character. 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; salt_string.append( c ); - if (++current_length >= length) + if ( ++current_length >= length ) + { break; + } } } @@ -112,34 +112,21 @@ SetPasswordJob::exec() return Calamares::JobResult::error( tr( "Bad destination system path." ), tr( "rootMountPoint is %1" ).arg( destDir.absolutePath() ) ); - if ( m_userName == "root" && - m_newPassword.isEmpty() ) //special case for disabling root account + if ( m_userName == "root" && m_newPassword.isEmpty() ) //special case for disabling root account { - int ec = CalamaresUtils::System::instance()-> - targetEnvCall( { "passwd", - "-dl", - m_userName } ); + int ec = CalamaresUtils::System::instance()->targetEnvCall( { "passwd", "-dl", m_userName } ); if ( ec ) return Calamares::JobResult::error( tr( "Cannot disable root account." ), - tr( "passwd terminated with error code %1." ) - .arg( ec ) ); + tr( "passwd terminated with error code %1." ).arg( ec ) ); return Calamares::JobResult::ok(); } - QString encrypted = QString::fromLatin1( - crypt( m_newPassword.toUtf8(), - make_salt( 16 ).toUtf8() ) ); + QString encrypted = QString::fromLatin1( crypt( m_newPassword.toUtf8(), make_salt( 16 ).toUtf8() ) ); - int ec = CalamaresUtils::System::instance()-> - targetEnvCall( { "usermod", - "-p", - encrypted, - m_userName } ); + int ec = CalamaresUtils::System::instance()->targetEnvCall( { "usermod", "-p", encrypted, m_userName } ); if ( ec ) - return Calamares::JobResult::error( tr( "Cannot set password for user %1." ) - .arg( m_userName ), - tr( "usermod terminated with error code %1." ) - .arg( ec ) ); + return Calamares::JobResult::error( tr( "Cannot set password for user %1." ).arg( m_userName ), + tr( "usermod terminated with error code %1." ).arg( ec ) ); return Calamares::JobResult::ok(); } diff --git a/src/modules/users/SetPasswordJob.h b/src/modules/users/SetPasswordJob.h index c4ec59c2a..d2ebf64aa 100644 --- a/src/modules/users/SetPasswordJob.h +++ b/src/modules/users/SetPasswordJob.h @@ -27,13 +27,12 @@ class SetPasswordJob : public Calamares::Job { Q_OBJECT public: - SetPasswordJob( const QString& userName, - const QString& newPassword ); + SetPasswordJob( const QString& userName, const QString& newPassword ); QString prettyName() const override; QString prettyStatusMessage() const override; Calamares::JobResult exec() override; - static QString make_salt(int length); + static QString make_salt( int length ); private: QString m_userName; diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 82568f81a..d7f7d27b3 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -27,8 +27,8 @@ #include "ui_page_usersetup.h" #include "CreateUserJob.h" -#include "SetPasswordJob.h" #include "SetHostNameJob.h" +#include "SetPasswordJob.h" #include "GlobalStorage.h" #include "JobQueue.h" @@ -74,30 +74,19 @@ UsersPage::UsersPage( QWidget* parent ) ui->setupUi( this ); // Connect signals and slots - connect( ui->textBoxFullName, &QLineEdit::textEdited, - this, &UsersPage::onFullNameTextEdited ); - connect( ui->textBoxUsername, &QLineEdit::textEdited, - this, &UsersPage::onUsernameTextEdited ); - connect( ui->textBoxHostname, &QLineEdit::textEdited, - this, &UsersPage::onHostnameTextEdited ); - connect( ui->textBoxUserPassword, &QLineEdit::textChanged, - this, &UsersPage::onPasswordTextChanged ); - 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 ) - { + connect( ui->textBoxFullName, &QLineEdit::textEdited, this, &UsersPage::onFullNameTextEdited ); + connect( ui->textBoxUsername, &QLineEdit::textEdited, this, &UsersPage::onUsernameTextEdited ); + connect( ui->textBoxHostname, &QLineEdit::textEdited, this, &UsersPage::onHostnameTextEdited ); + connect( ui->textBoxUserPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged ); + 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() ); onRootPasswordTextChanged( ui->textBoxRootPassword->text() ); checkReady( isReady() ); } ); - connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, - this, [this]( int checked ) - { + connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( int checked ) { ui->labelChooseRootPassword->setVisible( !checked ); ui->labelExtraRootPassword->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 // 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->hostname_extra_label_2->setMaximumWidth( 3 * boxWidth ); ui->password_extra_label_3->setMaximumWidth( 3 * boxWidth ); CALAMARES_RETRANSLATE( - ui->retranslateUi( this ); - if ( Calamares::Settings::instance()->isSetupMode() ) - { + ui->retranslateUi( this ); if ( Calamares::Settings::instance()->isSetupMode() ) { ui->username_extra_label_2->setText( tr( "If more than one person will " "use this computer, you can create multiple " "accounts after setup." ) ); - } - else - { + } else { ui->username_extra_label_2->setText( tr( "If more than one person will " "use this computer, you can create multiple " "accounts after installation." ) ); - } - ) + } ) } @@ -149,12 +134,11 @@ UsersPage::~UsersPage() bool UsersPage::isReady() { - bool readyFields = m_readyFullName && - m_readyHostname && - m_readyPassword && - m_readyUsername; + bool readyFields = m_readyFullName && m_readyHostname && m_readyPassword && m_readyUsername; if ( !m_writeRootPassword || ui->checkBoxReusePassword->isChecked() ) + { return readyFields; + } return readyFields && m_readyRootPassword; } @@ -165,38 +149,36 @@ UsersPage::createJobs( const QStringList& defaultGroupsList ) { QList< Calamares::job_ptr > list; if ( !isReady() ) + { return list; + } Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); Calamares::Job* j; j = new CreateUserJob( ui->textBoxUsername->text(), - ui->textBoxFullName->text().isEmpty() ? - ui->textBoxUsername->text() : - ui->textBoxFullName->text(), + ui->textBoxFullName->text().isEmpty() ? ui->textBoxUsername->text() + : ui->textBoxFullName->text(), ui->checkBoxAutoLogin->isChecked(), defaultGroupsList ); list.append( Calamares::job_ptr( j ) ); - j = new SetPasswordJob( ui->textBoxUsername->text(), - ui->textBoxUserPassword->text() ); + j = new SetPasswordJob( ui->textBoxUsername->text(), ui->textBoxUserPassword->text() ); list.append( Calamares::job_ptr( j ) ); if ( m_writeRootPassword ) { gs->insert( "reuseRootPassword", ui->checkBoxReusePassword->isChecked() ); if ( ui->checkBoxReusePassword->isChecked() ) - j = new SetPasswordJob( "root", - ui->textBoxUserPassword->text() ); + j = new SetPasswordJob( "root", ui->textBoxUserPassword->text() ); else - j = new SetPasswordJob( "root", - ui->textBoxRootPassword->text() ); + j = new SetPasswordJob( "root", ui->textBoxRootPassword->text() ); list.append( Calamares::job_ptr( j ) ); } else { j = new SetPasswordJob( "root", - "" ); //explicitly disable root password + "" ); //explicitly disable root password list.append( Calamares::job_ptr( j ) ); } @@ -205,7 +187,9 @@ UsersPage::createJobs( const QStringList& defaultGroupsList ) gs->insert( "hostname", ui->textBoxHostname->text() ); if ( ui->checkBoxAutoLogin->isChecked() ) + { gs->insert( "autologinUser", ui->textBoxUsername->text() ); + } gs->insert( "username", ui->textBoxUsername->text() ); gs->insert( "password", CalamaresUtils::obscure( ui->textBoxUserPassword->text() ) ); @@ -237,16 +221,19 @@ UsersPage::onFullNameTextEdited( const QString& textRef ) ui->labelFullNameError->clear(); ui->labelFullName->clear(); if ( !m_customUsername ) + { ui->textBoxUsername->clear(); + } if ( !m_customHostname ) + { ui->textBoxHostname->clear(); + } m_readyFullName = false; } else { - ui->labelFullName->setPixmap( CalamaresUtils::defaultPixmap( CalamaresUtils::Yes, - CalamaresUtils::Original, - ui->labelFullName->size() ) ); + ui->labelFullName->setPixmap( + CalamaresUtils::defaultPixmap( CalamaresUtils::Yes, CalamaresUtils::Original, ui->labelFullName->size() ) ); m_readyFullName = true; fillSuggestions(); } @@ -259,8 +246,7 @@ UsersPage::fillSuggestions() { QString fullName = ui->textBoxFullName->text(); QRegExp rx( "[^a-zA-Z0-9 ]", Qt::CaseInsensitive ); - QString cleanName = CalamaresUtils::removeDiacritics( fullName ) - .toLower().replace( rx, " " ).simplified(); + QString cleanName = CalamaresUtils::removeDiacritics( fullName ).toLower().replace( rx, " " ).simplified(); QStringList cleanParts = cleanName.split( ' ' ); if ( !m_customUsername ) @@ -271,7 +257,9 @@ UsersPage::fillSuggestions() for ( int i = 1; i < cleanParts.length(); ++i ) { if ( !cleanParts.value( i ).isEmpty() ) + { usernameSuggestion.append( cleanParts.value( i ).at( 0 ) ); + } } if ( USERNAME_RX.indexIn( usernameSuggestion ) != -1 ) { @@ -322,14 +310,15 @@ UsersPage::validateUsernameText( const QString& textRef ) } else if ( text.length() > USERNAME_MAX_LENGTH ) { - labelError( ui->labelUsername, ui->labelUsernameError, - tr( "Your username is too long." ) ); + labelError( ui->labelUsername, ui->labelUsernameError, tr( "Your username is too long." ) ); m_readyUsername = false; } else if ( val.validate( text, pos ) == QValidator::Invalid ) { - labelError( ui->labelUsername, ui->labelUsernameError, - tr( "Your username contains invalid characters. Only lowercase letters and numbers are allowed." ) ); + labelError( + ui->labelUsername, + ui->labelUsernameError, + tr( "Your username contains invalid characters. Only lowercase letters and numbers are allowed." ) ); m_readyUsername = false; } else @@ -362,23 +351,22 @@ UsersPage::validateHostnameText( const QString& textRef ) { ui->labelHostnameError->clear(); ui->labelHostname->clear(); - m_readyHostname= false; + m_readyHostname = false; } else if ( text.length() < HOSTNAME_MIN_LENGTH ) { - labelError( ui->labelHostname, ui->labelHostnameError, - tr( "Your hostname is too short." ) ); + 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." ) ); + 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, + labelError( ui->labelHostname, + ui->labelHostnameError, tr( "Your hostname contains invalid characters. Only letters, numbers and dashes are allowed." ) ); m_readyHostname = false; } @@ -407,8 +395,7 @@ UsersPage::onPasswordTextChanged( const QString& ) } else if ( pw1 != pw2 ) { - labelError( ui->labelUserPassword, ui->labelUserPasswordError, - tr( "Your passwords do not match!" ) ); + labelError( ui->labelUserPassword, ui->labelUserPasswordError, tr( "Your passwords do not match!" ) ); m_readyPassword = false; } else @@ -453,8 +440,7 @@ UsersPage::onRootPasswordTextChanged( const QString& ) } else if ( pw1 != pw2 ) { - labelError( ui->labelRootPassword, ui->labelRootPasswordError, - tr( "Your passwords do not match!" ) ); + labelError( ui->labelRootPassword, ui->labelRootPasswordError, tr( "Your passwords do not match!" ) ); m_readyRootPassword = false; } else @@ -527,7 +513,9 @@ UsersPage::addPasswordCheck( const QString& key, const QVariant& value ) { add_check_libpwquality( m_passwordChecks, value ); } -#endif // CHECK_PWQUALITY +#endif // CHECK_PWQUALITY else + { cWarning() << "Unknown password-check key" << key; + } } diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index 2dbe7aeda..9deb1d253 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -96,4 +96,4 @@ private: bool m_writeRootPassword; }; -#endif // USERSPAGE_H +#endif // USERSPAGE_H diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index b08223a0b..11f5693e9 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -29,22 +29,23 @@ #include "GlobalStorage.h" #include "JobQueue.h" -CALAMARES_PLUGIN_FACTORY_DEFINITION( UsersViewStepFactory, registerPlugin(); ) +CALAMARES_PLUGIN_FACTORY_DEFINITION( UsersViewStepFactory, registerPlugin< UsersViewStep >(); ) UsersViewStep::UsersViewStep( QObject* parent ) : Calamares::ViewStep( parent ) , m_widget( new UsersPage() ) { emit nextStatusChanged( true ); - connect( m_widget, &UsersPage::checkReady, - this, &UsersViewStep::nextStatusChanged ); + connect( m_widget, &UsersPage::checkReady, this, &UsersViewStep::nextStatusChanged ); } UsersViewStep::~UsersViewStep() { if ( m_widget && m_widget->parent() == nullptr ) + { m_widget->deleteLater(); + } } @@ -116,80 +117,80 @@ UsersViewStep::onLeave() void UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { - if ( configurationMap.contains( "defaultGroups" ) && - configurationMap.value( "defaultGroups" ).type() == QVariant::List ) + if ( configurationMap.contains( "defaultGroups" ) + && configurationMap.value( "defaultGroups" ).type() == QVariant::List ) { m_defaultGroups = configurationMap.value( "defaultGroups" ).toStringList(); } else { 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" ) && - configurationMap.value( "autologinGroup" ).type() == QVariant::String ) + if ( configurationMap.contains( "autologinGroup" ) + && configurationMap.value( "autologinGroup" ).type() == QVariant::String ) { - Calamares::JobQueue::instance()->globalStorage()->insert( "autologinGroup", - configurationMap.value( "autologinGroup" ).toString() ); + Calamares::JobQueue::instance()->globalStorage()->insert( + "autologinGroup", configurationMap.value( "autologinGroup" ).toString() ); } - if ( configurationMap.contains( "sudoersGroup" ) && - configurationMap.value( "sudoersGroup" ).type() == QVariant::String ) + if ( configurationMap.contains( "sudoersGroup" ) + && configurationMap.value( "sudoersGroup" ).type() == QVariant::String ) { Calamares::JobQueue::instance()->globalStorage()->insert( "sudoersGroup", - configurationMap.value( "sudoersGroup" ).toString() ); + configurationMap.value( "sudoersGroup" ).toString() ); } - if ( configurationMap.contains( "setRootPassword" ) && - configurationMap.value( "setRootPassword" ).type() == QVariant::Bool ) + if ( configurationMap.contains( "setRootPassword" ) + && configurationMap.value( "setRootPassword" ).type() == QVariant::Bool ) { - Calamares::JobQueue::instance()->globalStorage()->insert( "setRootPassword", - configurationMap.value( "setRootPassword" ).toBool() ); + Calamares::JobQueue::instance()->globalStorage()->insert( + "setRootPassword", configurationMap.value( "setRootPassword" ).toBool() ); m_widget->setWriteRootPassword( configurationMap.value( "setRootPassword" ).toBool() ); } - if ( configurationMap.contains( "doAutologin" ) && - configurationMap.value( "doAutologin" ).type() == QVariant::Bool ) + if ( configurationMap.contains( "doAutologin" ) + && configurationMap.value( "doAutologin" ).type() == QVariant::Bool ) { m_widget->setAutologinDefault( configurationMap.value( "doAutologin" ).toBool() ); } - if ( configurationMap.contains( "doReusePassword" ) && - configurationMap.value( "doReusePassword" ).type() == QVariant::Bool ) + if ( configurationMap.contains( "doReusePassword" ) + && configurationMap.value( "doReusePassword" ).type() == QVariant::Bool ) { m_widget->setReusePasswordDefault( configurationMap.value( "doReusePassword" ).toBool() ); } - if ( configurationMap.contains( "passwordRequirements" ) && - configurationMap.value( "passwordRequirements" ).type() == QVariant::Map ) + 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) + for ( decltype( pr_checks )::const_iterator i = pr_checks.constBegin(); i != pr_checks.constEnd(); ++i ) { m_widget->addPasswordCheck( i.key(), i.value() ); } } - if ( configurationMap.contains( "allowWeakPasswords" ) && - configurationMap.value( "allowWeakPasswords" ).type() == QVariant::Bool ) + if ( configurationMap.contains( "allowWeakPasswords" ) + && configurationMap.value( "allowWeakPasswords" ).type() == QVariant::Bool ) { m_widget->setPasswordCheckboxVisible( configurationMap.value( "allowWeakPasswords" ).toBool() ); } - if ( configurationMap.contains( "doPasswordChecks" ) && - configurationMap.value( "doPasswordChecks" ).type() == QVariant::Bool ) + if ( configurationMap.contains( "doPasswordChecks" ) + && configurationMap.value( "doPasswordChecks" ).type() == QVariant::Bool ) { m_widget->setValidatePasswordDefault( configurationMap.value( "doPasswordChecks" ).toBool() ); } QString shell( QLatin1String( "/bin/bash" ) ); // as if it's not set at all if ( configurationMap.contains( "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 ); } - diff --git a/src/modules/users/UsersViewStep.h b/src/modules/users/UsersViewStep.h index a1995497c..6fced76b9 100644 --- a/src/modules/users/UsersViewStep.h +++ b/src/modules/users/UsersViewStep.h @@ -65,4 +65,4 @@ private: CALAMARES_PLUGIN_FACTORY_DECLARATION( UsersViewStepFactory ) -#endif // USERSPAGEPLUGIN_H +#endif // USERSPAGEPLUGIN_H From 21bcd560b1f829e52ee65a8680bdd00e0ff34104 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 21 Oct 2019 17:26:06 +0200 Subject: [PATCH 03/22] [users] Use API to change weak-checkbox visibility --- src/modules/users/UsersPage.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index d7f7d27b3..7bc0e5dbb 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -102,7 +102,8 @@ UsersPage::UsersPage( QWidget* parent ) setWriteRootPassword( true ); ui->checkBoxReusePassword->setChecked( true ); ui->checkBoxValidatePassword->setChecked( true ); - ui->checkBoxValidatePassword->setVisible( false ); + + setPasswordCheckboxVisible( false ); // Don't expand the explanations to "stupid wide", but keep them vaguely as-wide-as // the things they are explaining. From ede50756a146e31508692dadaaf856ec01a58c64 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 21 Oct 2019 17:29:35 +0200 Subject: [PATCH 04/22] [users] Simplify config-logic for weak-passwords - Use the convenience methods for config-reading. - Always set the value (to the default if nog explicitly set in the config-file). --- src/modules/users/UsersViewStep.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 11f5693e9..b6072c741 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -173,11 +173,7 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } } - if ( configurationMap.contains( "allowWeakPasswords" ) - && configurationMap.value( "allowWeakPasswords" ).type() == QVariant::Bool ) - { - m_widget->setPasswordCheckboxVisible( configurationMap.value( "allowWeakPasswords" ).toBool() ); - } + m_widget->setPasswordCheckboxVisible( CalamaresUtils::getBool( configurationMap, "allowWeakPasswords", false ) ); if ( configurationMap.contains( "doPasswordChecks" ) && configurationMap.value( "doPasswordChecks" ).type() == QVariant::Bool ) From c030cc41cde659f4ffece97cae7292ff48979aa9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Oct 2019 15:03:37 +0200 Subject: [PATCH 05/22] [libcalamaresui] Refactor button-creation - The "convenience" method was no longer convenient, since we now place strings on the buttons by default. - While here, **name** the buttons so they can be themed. --- src/libcalamaresui/ViewManager.cpp | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 06fd97009..68d918971 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -75,26 +75,6 @@ setButtonIcon( QPushButton* button, const QString& name ) } } -/** @brief Creates a button with a given icon-name - * - * Creates a new button as child of @p parent. - * Sets the named icon, if it exists, onto the button. - * Returns the new button. - * - * There is a QPushButton constructor that takes an icon, - * but it also needs a text and we've got translations - * to worry about as well as state. - */ -static inline QPushButton* -makeButton( QWidget* parent, const QString& name, const QString& label ) -{ - QPushButton* button = new QPushButton( parent ); - button->setObjectName( name ); - button->setText( label ); - setButtonIcon( button, name ); - return button; -} - ViewManager::ViewManager( QObject* parent ) : QObject( parent ) , m_currentStep( 0 ) @@ -110,9 +90,12 @@ ViewManager::ViewManager( QObject* parent ) mainLayout->addWidget( m_stack ); // Create buttons and sets an initial icon; the icons may change - m_back = makeButton( m_widget, QStringLiteral( "go-previous" ), tr( "&Back" ) ); - m_next = makeButton( m_widget, QStringLiteral( "go-next" ), tr( "&Next" ) ); - m_quit = makeButton( m_widget, QStringLiteral( "dialog-cancel" ), tr( "&Cancel" ) ); + m_back = new QPushButton( getButtonIcon( QStringLiteral( "go-previous" ) ), tr( "&Back" ), m_widget ); + m_back->setObjectName( "view-button-back" ); + m_next = new QPushButton( getButtonIcon( QStringLiteral( "go-next" ) ), tr( "&Next" ), m_widget ); + m_next->setObjectName( "view-button-next" ); + m_quit = new QPushButton( getButtonIcon( QStringLiteral( "dialog-cancel" ) ), tr( "&Cancel" ), m_widget ); + m_quit->setObjectName( "view-button-cancel" ); CALAMARES_RETRANSLATE_SLOT( &ViewManager::updateButtonLabels ) From 3e4e492305bc2d06d750b4384f24b737ecd8b84f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Oct 2019 15:32:42 +0200 Subject: [PATCH 06/22] [users] Polish the documentation for the various checkboxes --- src/modules/users/users.conf | 54 ++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/modules/users/users.conf b/src/modules/users/users.conf index 0942e6b5d..2e164cf13 100644 --- a/src/modules/users/users.conf +++ b/src/modules/users/users.conf @@ -27,26 +27,34 @@ defaultGroups: # the desktop environment on boot. # Disable when your Distribution does not require such a group. autologinGroup: autologin -# You can control the initial state for the 'autologin checkbox' in UsersViewStep here. -# Possible values are: true to enable or false to disable the checkbox by default. +# You can control the initial state for the 'autologin checkbox' here. +# Possible values are: +# - true to check or +# - false to uncheck +# These set the **initial** state of the checkbox. doAutologin: true -# When set to a non-empty string, Calamares creates a sudoers file for the user. -# /etc/sudoers.d/10-installer -# Remember to add sudoersGroup to defaultGroups. +# When *sudoersGroup* is set to a non-empty string, Calamares creates a +# sudoers file for the user. This file is located at: +# `/etc/sudoers.d/10-installer` +# Remember to add the (value of) *sudoersGroup* to *defaultGroups*. # # If your Distribution already sets up a group of sudoers in its packaging, # remove this setting (delete or comment out the line below). Otherwise, -# the setting will be duplicated in the /etc/sudoers.d/10-installer file, +# the setting will be duplicated in the `/etc/sudoers.d/10-installer` file, # potentially confusing users. sudoersGroup: wheel # Setting this to false , causes the root account to be disabled. setRootPassword: true -# You can control the initial state for the 'root password checkbox' in UsersViewStep here. -# Possible values are: true to enable or false to disable the checkbox by default. -# When enabled the user password is used for the root account too. -# NOTE: doReusePassword requires setRootPassword to be enabled. +# You can control the initial state for the 'reuse password for root' +# checkbox here. Possible values are: +# - true to check or +# - false to uncheck +# +# When checked, the user password is used for the root account too. +# +# NOTE: *doReusePassword* requires *setRootPassword* to be enabled. doReusePassword: true # These are optional password-requirements that a distro can enforce @@ -69,21 +77,31 @@ doReusePassword: true # (additional checks may be implemented in CheckPWQuality.cpp and # wired into UsersPage.cpp) # -# To disable specific password validations, -# comment out the relevant 'passwordRequirements' keys below. -# To disable all password validations, -# set both 'allowWeakPasswords' and 'doPasswordChecks' to false. +# - To disable specific password validations: +# comment out the relevant 'passwordRequirements' keys below. +# - To disable all password validations: +# set both 'allowWeakPasswords' and 'allowWeakPasswordsDefault' to true. +# (This will show the box *Allow weak passwords* in the user- +# interface, and check it by default). passwordRequirements: minLength: -1 # Password at least this many characters maxLength: -1 # Password at most this many characters libpwquality: - minlen=0 - minclass=0 -# You can control the visibility of the 'strong passwords' checkbox in UsersViewStep here. -# Possible values are: true to show or false to hide the checkbox. + +# You can control the visibility of the 'weak passwords' checkbox here. +# Possible values are: +# - true to show or +# - false to hide +# the checkbox. This checkbox allows the user to choose to disable +# password-strength-checks. allowWeakPasswords: true -# You can control the initial state for the 'strong passwords' checkbox in UsersViewStep here. -# Possible values are: true to enable or false to disable the checkbox by default. +# You can control the initial state for the 'weak passwords' checkbox here. +# Possible values are: +# - true to check or +# - false to uncheck +# the checkbox by default. doPasswordChecks: true # Shell to be used for the regular user of the target system. From b3765bc144686d759db49dbcc6d549934cfaf005 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Oct 2019 16:08:21 +0200 Subject: [PATCH 07/22] [users] Massage the weak-passwords settings - since the wording of the checkbox itself (and the functionality) is to enforce strong passwords, need to switch out some logic and fix the wording of the documentation. --- src/modules/users/UsersViewStep.cpp | 7 +------ src/modules/users/users.conf | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index b6072c741..b898f00c8 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -174,12 +174,7 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } m_widget->setPasswordCheckboxVisible( CalamaresUtils::getBool( configurationMap, "allowWeakPasswords", false ) ); - - if ( configurationMap.contains( "doPasswordChecks" ) - && configurationMap.value( "doPasswordChecks" ).type() == QVariant::Bool ) - { - m_widget->setValidatePasswordDefault( configurationMap.value( "doPasswordChecks" ).toBool() ); - } + m_widget->setValidatePasswordDefault( !CalamaresUtils::getBool( configurationMap, "allowWeakPasswordsDefault", false) ); QString shell( QLatin1String( "/bin/bash" ) ); // as if it's not set at all if ( configurationMap.contains( "userShell" ) ) diff --git a/src/modules/users/users.conf b/src/modules/users/users.conf index 2e164cf13..cae9bef0d 100644 --- a/src/modules/users/users.conf +++ b/src/modules/users/users.conf @@ -81,7 +81,7 @@ doReusePassword: true # comment out the relevant 'passwordRequirements' keys below. # - To disable all password validations: # set both 'allowWeakPasswords' and 'allowWeakPasswordsDefault' to true. -# (This will show the box *Allow weak passwords* in the user- +# (That will show the box *Allow weak passwords* in the user- # interface, and check it by default). passwordRequirements: minLength: -1 # Password at least this many characters @@ -90,19 +90,22 @@ passwordRequirements: - minlen=0 - minclass=0 -# You can control the visibility of the 'weak passwords' checkbox here. +# You can control the visibility of the 'strong passwords' checkbox here. # Possible values are: # - true to show or -# - false to hide +# - false to hide (default) # the checkbox. This checkbox allows the user to choose to disable -# password-strength-checks. -allowWeakPasswords: true -# You can control the initial state for the 'weak passwords' checkbox here. +# password-strength-checks. By default the box is **hidden**, so +# that you have to pick a password that satisfies the checks. +allowWeakPasswords: false +# You can control the initial state for the 'strong passwords' checkbox here. # Possible values are: -# - true to check or -# - false to uncheck -# the checkbox by default. -doPasswordChecks: true +# - true to uncheck or +# - false to check (default) +# the checkbox by default. Since the box is labeled to enforce strong +# passwords, in order to **allow** weak ones by default, the box needs +# to be unchecked. +allowWeakPasswordsDefault: false # Shell to be used for the regular user of the target system. # There are three possible kinds of settings: From 9ee0609b7223f32193c49ed92285dde5ae50da1b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 29 Oct 2019 14:37:26 +0100 Subject: [PATCH 08/22] [users] Use tooltips - the explanations under and around the boxes is noisy, hard to size correctly (viz. issue #1202) - use tooltips in almost-all fields instead - add placeholder text to be more suggestive --- src/modules/users/UsersPage.cpp | 24 ++++---- src/modules/users/page_usersetup.ui | 91 +++++++++++++---------------- 2 files changed, 49 insertions(+), 66 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 7bc0e5dbb..1290f0114 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -88,7 +88,6 @@ UsersPage::UsersPage( QWidget* parent ) } ); connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( int checked ) { ui->labelChooseRootPassword->setVisible( !checked ); - ui->labelExtraRootPassword->setVisible( !checked ); ui->labelRootPassword->setVisible( !checked ); ui->labelRootPasswordError->setVisible( !checked ); ui->textBoxRootPassword->setVisible( !checked ); @@ -105,24 +104,21 @@ UsersPage::UsersPage( QWidget* parent ) setPasswordCheckboxVisible( false ); - // Don't expand the explanations to "stupid wide", but keep them vaguely as-wide-as - // the things they are explaining. - int boxWidth - = qMax( qMax( ui->textBoxUsername->width(), ui->textBoxHostname->width() ), ui->textBoxUserPassword->width() ); - ui->username_extra_label_2->setMaximumWidth( 3 * boxWidth ); - ui->hostname_extra_label_2->setMaximumWidth( 3 * boxWidth ); - ui->password_extra_label_3->setMaximumWidth( 3 * boxWidth ); - CALAMARES_RETRANSLATE( - ui->retranslateUi( this ); if ( Calamares::Settings::instance()->isSetupMode() ) { - ui->username_extra_label_2->setText( tr( "If more than one person will " + ui->retranslateUi( this ); + if ( Calamares::Settings::instance()->isSetupMode() ) + { + ui->textBoxUsername->setToolTip( tr( "If more than one person will " "use this computer, you can create multiple " "accounts after setup." ) ); - } else { - ui->username_extra_label_2->setText( tr( "If more than one person will " + } + else + { + ui->textBoxUsername->setToolTip( tr( "If more than one person will " "use this computer, you can create multiple " "accounts after installation." ) ); - } ) + } + ) } diff --git a/src/modules/users/page_usersetup.ui b/src/modules/users/page_usersetup.ui index ae74255c2..b778647d8 100644 --- a/src/modules/users/page_usersetup.ui +++ b/src/modules/users/page_usersetup.ui @@ -47,6 +47,9 @@ 0 + + Your Full Name + @@ -137,6 +140,9 @@ 0 + + login + @@ -191,19 +197,6 @@ - - - - font-weight: normal - - - <Username extra label 2 text> - - - true - - - @@ -246,6 +239,12 @@ 0 + + <small>This name will be used if you make the computer visible to others on a network.</small> + + + Computer Name + @@ -300,19 +299,6 @@ - - - - font-weight: normal - - - <small>This name will be used if you make the computer visible to others on a network.</small> - - - false - - - @@ -355,9 +341,15 @@ 0 + + <small>Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals.</small> + QLineEdit::Password + + Password + @@ -374,9 +366,15 @@ 0 + + <small>Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals.</small> + QLineEdit::Password + + Repeat Password + @@ -431,19 +429,6 @@ - - - - font-weight: normal - - - <small>Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals.</small> - - - true - - - @@ -462,6 +447,9 @@ + + When this box is checked, password-strength checking is done and you will not be able to use a weak password. + Require strong passwords. @@ -523,9 +511,15 @@ 0 + + <small>Enter the same password twice, so that it can be checked for typing errors.</small> + QLineEdit::Password + + Password + @@ -542,9 +536,15 @@ 0 + + <small>Enter the same password twice, so that it can be checked for typing errors.</small> + QLineEdit::Password + + Repeat Password + @@ -599,19 +599,6 @@ - - - - font-weight: normal - - - <small>Enter the same password twice, so that it can be checked for typing errors.</small> - - - true - - - From 9cd1ef93bdf873ee496230385f05584a0c4ab510 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 29 Oct 2019 16:20:52 +0100 Subject: [PATCH 09/22] [users] Apply coding style --- src/modules/users/UsersPage.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 1290f0114..579162675 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -167,9 +167,13 @@ UsersPage::createJobs( const QStringList& defaultGroupsList ) { gs->insert( "reuseRootPassword", ui->checkBoxReusePassword->isChecked() ); if ( ui->checkBoxReusePassword->isChecked() ) + { j = new SetPasswordJob( "root", ui->textBoxUserPassword->text() ); + } else + { j = new SetPasswordJob( "root", ui->textBoxRootPassword->text() ); + } list.append( Calamares::job_ptr( j ) ); } else From 8232ca626c6ea6a6adc15f1329420f93c7c28d4b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 29 Oct 2019 16:21:26 +0100 Subject: [PATCH 10/22] [users] Refactor constants --- src/modules/users/UsersPage.cpp | 12 ++++++++---- src/modules/users/UsersPage.h | 6 ------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 579162675..a60532022 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -45,6 +45,12 @@ #include #include +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; +static constexpr const int HOSTNAME_MAX_LENGTH = 63; + /** Add an error message and pixmap to a label. */ static inline void labelError( QLabel* pix, QLabel* label, const QString& message ) @@ -299,8 +305,7 @@ void UsersPage::validateUsernameText( const QString& textRef ) { QString text( textRef ); - QRegExp rx( USERNAME_RX ); - QRegExpValidator val( rx ); + QRegExpValidator val( USERNAME_RX ); int pos = -1; if ( text.isEmpty() ) @@ -344,8 +349,7 @@ void UsersPage::validateHostnameText( const QString& textRef ) { QString text = textRef; - QRegExp rx( HOSTNAME_RX ); - QRegExpValidator val( rx ); + QRegExpValidator val( HOSTNAME_RX ); int pos = -1; if ( text.isEmpty() ) diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index 9deb1d253..d8aed07fc 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -79,12 +79,6 @@ private: PasswordCheckList m_passwordChecks; - const QRegExp USERNAME_RX = QRegExp( "^[a-z_][a-z0-9_-]*[$]?$" ); - const QRegExp HOSTNAME_RX = QRegExp( "^[a-zA-Z0-9][-a-zA-Z0-9_]*$" ); - const int USERNAME_MAX_LENGTH = 31; - const int HOSTNAME_MIN_LENGTH = 2; - const int HOSTNAME_MAX_LENGTH = 63; - bool m_readyFullName; bool m_readyUsername; bool m_customUsername; From 93eb169ea53f93a5a778567e4cc33253aff80094 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 13:05:58 +0100 Subject: [PATCH 11/22] [users] Improve error messages - distinguish beginning of username from the rest - must start with a letter or _ - tighten message for bad username and bad hostname FIXES #1261 --- src/modules/users/UsersPage.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index a60532022..acb4f79b6 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -305,7 +305,8 @@ void UsersPage::validateUsernameText( const QString& textRef ) { QString text( textRef ); - QRegExpValidator val( USERNAME_RX ); + QRegExpValidator val_whole( USERNAME_RX ); + QRegExpValidator val_start( QRegExp( "[a-z_].*" ) ); // anchors are implicit in QRegExpValidator int pos = -1; if ( text.isEmpty() ) @@ -319,12 +320,20 @@ UsersPage::validateUsernameText( const QString& textRef ) labelError( ui->labelUsername, ui->labelUsernameError, tr( "Your username is too long." ) ); m_readyUsername = false; } - else if ( val.validate( text, pos ) == QValidator::Invalid ) + else if ( val_start.validate( text, pos ) == QValidator::Invalid ) { labelError( ui->labelUsername, ui->labelUsernameError, - tr( "Your username contains invalid characters. Only lowercase letters and numbers are allowed." ) ); + 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 @@ -372,7 +381,7 @@ UsersPage::validateHostnameText( const QString& textRef ) { labelError( ui->labelHostname, ui->labelHostnameError, - tr( "Your hostname contains invalid characters. Only letters, numbers and dashes are allowed." ) ); + tr( "Only letters, numbers, underscore and hyphen are allowed." ) ); m_readyHostname = false; } else From 7d25173afbb05719e38db30d4ff93e7d91430a0e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 13:17:31 +0100 Subject: [PATCH 12/22] [users] Remove TODO since it doesn't make sense - the two explicit checks are the ones that handle *two* strings as special cases; all the other checks from the password-requirements system only handle the one string. --- src/modules/users/UsersPage.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index acb4f79b6..287a771ea 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -400,7 +400,6 @@ UsersPage::onPasswordTextChanged( const QString& ) QString pw2 = ui->textBoxUserVerifiedPassword->text(); m_readyPassword = true; - // TODO: 3.3: remove empty-check and leave it to passwordRequirements if ( pw1.isEmpty() && pw2.isEmpty() ) { ui->labelUserPasswordError->clear(); @@ -445,7 +444,6 @@ UsersPage::onRootPasswordTextChanged( const QString& ) QString pw2 = ui->textBoxVerifiedRootPassword->text(); m_readyRootPassword = true; - // TODO: 3.3: remove empty-check and leave it to passwordRequirements if ( pw1.isEmpty() && pw2.isEmpty() ) { ui->labelRootPasswordError->clear(); From 9fa817a244b327636f2e30042e49595dd6a12a48 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 13:38:14 +0100 Subject: [PATCH 13/22] [users] Refactor password-validation - add a method that does the work and sets UI strings for a generic double-field password entry - use that for user and root passwords --- src/modules/users/UsersPage.cpp | 80 ++++++++++----------------------- src/modules/users/UsersPage.h | 10 +++++ 2 files changed, 34 insertions(+), 56 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 287a771ea..9f4f31f9d 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -393,23 +393,19 @@ UsersPage::validateHostnameText( const QString& textRef ) emit checkReady( isReady() ); } -void -UsersPage::onPasswordTextChanged( const QString& ) +bool +UsersPage::checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLabel* badge, QLabel* message ) { - QString pw1 = ui->textBoxUserPassword->text(); - QString pw2 = ui->textBoxUserVerifiedPassword->text(); - m_readyPassword = true; - if ( pw1.isEmpty() && pw2.isEmpty() ) { - ui->labelUserPasswordError->clear(); - ui->labelUserPassword->clear(); - m_readyPassword = false; + badge->clear(); + message->clear(); + return false; } else if ( pw1 != pw2 ) { - labelError( ui->labelUserPassword, ui->labelUserPasswordError, tr( "Your passwords do not match!" ) ); - m_readyPassword = false; + labelError( badge, message, tr( "Your passwords do not match!" ) ); + return false; } else { @@ -421,18 +417,24 @@ UsersPage::onPasswordTextChanged( const QString& ) if ( !s.isEmpty() ) { - labelError( ui->labelUserPassword, ui->labelUserPasswordError, s ); - m_readyPassword = false; - break; + labelError( badge, message, s ); + return false; } } } - if ( m_readyPassword ) - { - labelOk( ui->labelUserPassword, ui->labelUserPasswordError ); - } + labelOk( badge, message ); + return true; } +} + +void +UsersPage::onPasswordTextChanged( const QString& ) +{ + m_readyPassword = checkPasswordAcceptance( ui->textBoxUserPassword->text(), + ui->textBoxUserVerifiedPassword->text(), + ui->labelUserPassword, + ui->labelUserPasswordError ); emit checkReady( isReady() ); } @@ -440,44 +442,10 @@ UsersPage::onPasswordTextChanged( const QString& ) void UsersPage::onRootPasswordTextChanged( const QString& ) { - QString pw1 = ui->textBoxRootPassword->text(); - QString pw2 = ui->textBoxVerifiedRootPassword->text(); - m_readyRootPassword = true; - - if ( pw1.isEmpty() && pw2.isEmpty() ) - { - ui->labelRootPasswordError->clear(); - ui->labelRootPassword->clear(); - m_readyRootPassword = false; - } - else if ( pw1 != pw2 ) - { - labelError( ui->labelRootPassword, ui->labelRootPasswordError, tr( "Your passwords do not match!" ) ); - m_readyRootPassword = false; - } - else - { - if ( ui->checkBoxValidatePassword->isChecked() ) - { - for ( auto pc : m_passwordChecks ) - { - QString s = pc.filter( pw1 ); - - if ( !s.isEmpty() ) - { - labelError( ui->labelRootPassword, ui->labelRootPasswordError, s ); - m_readyRootPassword = false; - break; - } - } - } - - if ( m_readyRootPassword ) - { - labelOk( ui->labelRootPassword, ui->labelRootPasswordError ); - } - } - + m_readyRootPassword = checkPasswordAcceptance( ui->textBoxRootPassword->text(), + ui->textBoxVerifiedRootPassword->text(), + ui->labelRootPassword, + ui->labelRootPasswordError ); emit checkReady( isReady() ); } diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index d8aed07fc..520ce64a8 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -29,6 +29,8 @@ #include +class QLabel; + namespace Ui { class Page_UserSetup; @@ -75,6 +77,14 @@ signals: void checkReady( bool ); private: + /** @brief Is the password acceptable? + * + * Checks the two copies of the password and places error messages in the + * given QLabels. Returns true (and clears the error messages) if the + * password is acceptable. + */ + bool checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLabel* badge, QLabel* message ); + Ui::Page_UserSetup* ui; PasswordCheckList m_passwordChecks; From 28c9da414b3dfcd6c5ae218d5492adc5f470a8fd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 13:39:16 +0100 Subject: [PATCH 14/22] [users] Apply coding style --- src/modules/users/UsersPage.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 9f4f31f9d..cd93b8079 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -322,18 +322,16 @@ UsersPage::validateUsernameText( const QString& textRef ) } 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." ) ); + 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." ) ); + labelError( ui->labelUsername, + ui->labelUsernameError, + tr( "Only lowercase letters, numbers, underscore and hyphen are allowed." ) ); m_readyUsername = false; } else From a4e3ea2a8677ae56df80424ea411b9412e140ada Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 13:46:07 +0100 Subject: [PATCH 15/22] [users] Refactor retranslation - move retranslation to a method so that code-formatting doesn't get confused by it. --- src/modules/users/UsersPage.cpp | 37 ++++++++++++++++++--------------- src/modules/users/UsersPage.h | 2 ++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index cd93b8079..5d831b568 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -107,32 +107,35 @@ UsersPage::UsersPage( QWidget* parent ) setWriteRootPassword( true ); ui->checkBoxReusePassword->setChecked( true ); ui->checkBoxValidatePassword->setChecked( true ); - + setPasswordCheckboxVisible( false ); - CALAMARES_RETRANSLATE( - ui->retranslateUi( this ); - if ( Calamares::Settings::instance()->isSetupMode() ) - { - ui->textBoxUsername->setToolTip( tr( "If more than one person will " - "use this computer, you can create multiple " - "accounts after setup." ) ); - } - else - { - ui->textBoxUsername->setToolTip( tr( "If more than one person will " - "use this computer, you can create multiple " - "accounts after installation." ) ); - } - ) + CALAMARES_RETRANSLATE_SLOT( &UsersPage::retranslate ); } - UsersPage::~UsersPage() { delete ui; } +void +UsersPage::retranslate() +{ + ui->retranslateUi( this ); + if ( Calamares::Settings::instance()->isSetupMode() ) + { + ui->textBoxUsername->setToolTip( tr( "If more than one person will " + "use this computer, you can create multiple " + "accounts after setup." ) ); + } + else + { + ui->textBoxUsername->setToolTip( tr( "If more than one person will " + "use this computer, you can create multiple " + "accounts after installation." ) ); + } +} + bool UsersPage::isReady() diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index 520ce64a8..a2befbd26 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -85,6 +85,8 @@ private: */ bool checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLabel* badge, QLabel* message ); + void retranslate(); + Ui::Page_UserSetup* ui; PasswordCheckList m_passwordChecks; From 196a358493eb56d320caf88edf26d11137453d87 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 14:48:46 +0100 Subject: [PATCH 16/22] [users] Flag password problems even when weak-passwords are ok - when you allow weak passwords, flag problems as warnings (yellow) - when weak passwords aren't allowed, they are fatal errors (red) --- src/modules/users/UsersPage.cpp | 41 +++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index 5d831b568..c0965a7ed 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -51,12 +51,22 @@ 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 +{ + Fatal, + Warning +}; + /** Add an error message and pixmap to a label. */ static inline void -labelError( QLabel* pix, QLabel* label, const QString& message ) +labelError( QLabel* pix, QLabel* label, const QString& message, Badness bad = Badness::Fatal ) { label->setText( message ); - pix->setPixmap( CalamaresUtils::defaultPixmap( CalamaresUtils::No, CalamaresUtils::Original, label->size() ) ); + pix->setPixmap( CalamaresUtils::defaultPixmap( ( bad == Badness::Fatal ) ? CalamaresUtils::StatusError + : CalamaresUtils::StatusWarning, + CalamaresUtils::Original, + label->size() ) ); } /** Clear error, indicate OK on a label. */ @@ -399,6 +409,7 @@ UsersPage::checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLab { if ( pw1.isEmpty() && pw2.isEmpty() ) { + // Not exactly labelOk() because we also don't want a checkmark OK badge->clear(); message->clear(); return false; @@ -410,21 +421,31 @@ UsersPage::checkPasswordAcceptance( const QString& pw1, const QString& pw2, QLab } else { - if ( ui->checkBoxValidatePassword->isChecked() ) - { - for ( auto pc : m_passwordChecks ) - { - QString s = pc.filter( pw1 ); + bool failureIsFatal = ui->checkBoxValidatePassword->isChecked(); + bool failureFound = false; - if ( !s.isEmpty() ) + for ( auto pc : m_passwordChecks ) + { + QString s = pc.filter( pw1 ); + + if ( !s.isEmpty() ) + { + labelError( badge, message, s, failureIsFatal ? Badness::Fatal : Badness::Warning ); + failureFound = true; + if ( failureIsFatal ) { - labelError( badge, message, s ); return false; } } } - labelOk( badge, message ); + if ( !failureFound ) + { + labelOk( badge, message ); + } + + // Here, if failureFound is true then we've found **warnings**, + // which is ok to continue but the user should know. return true; } } From 699df6328f5cc310792918e93152d540e57a2e44 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 15:07:52 +0100 Subject: [PATCH 17/22] Changes: document this branch --- CHANGES | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index e5e3c42ba..aca4d6d5e 100644 --- a/CHANGES +++ b/CHANGES @@ -6,13 +6,22 @@ website will have to do for older versions. # 3.2.16 (unreleased) # This release contains contributions from (alphabetically by first name): - - No other contributors this time around. + - Bill Auger ## Core ## - - No changes to core functionality + - Some obscure build scenarios which would lead to bogus module-is- + misconfigured messages on startup have been resolved. ## Modules ## - - No changes to module functionality + - The explanatory messages on the *users* page have moved to tooltips, + and placeholder text has been added to the fields. #1202 + - The bad-password messages in the *users* page have been improved. #1261 + - Password-checking in the *users* module has been substantially + changed. A new key *allowWeakPasswords* can be used to introduce + an additional checkbox to the page, which can then be used to + switch off strict password checking. (Thanks to Bill Auger) + - The icons used in password warnings on the *users* page have been + changed to the colorful status icons (rather than the thin red X). # 3.2.15 (2019-10-11) # From 9497540b64574f3b0c8694798a8a921b603002e2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 17:19:23 +0100 Subject: [PATCH 18/22] Changes: pre-release housekeeping --- CHANGES | 14 +++++++++++++- CMakeLists.txt | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index aca4d6d5e..374fa320c 100644 --- a/CHANGES +++ b/CHANGES @@ -3,7 +3,19 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -# 3.2.16 (unreleased) # +# 3.2.17 (unreleased) # + +This release contains contributions from (alphabetically by first name): + - No external contributions. + +## Core ## + - No changes to core functionality + +## Modules ## + - No changes to module functionality + + +# 3.2.16 (2019-11-01) # This release contains contributions from (alphabetically by first name): - Bill Auger diff --git a/CMakeLists.txt b/CMakeLists.txt index ad92c3b62..2c970a5d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,7 @@ project( CALAMARES VERSION 3.2.16 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development ### OPTIONS # From 2edb204c9e0fbbc8a5858ddf77f4c171d338c6fd Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 1 Nov 2019 17:24:10 +0100 Subject: [PATCH 19/22] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_fr.ts | 2 +- lang/calamares_it_IT.ts | 70 +++++++------- lang/calamares_ja.ts | 2 +- lang/calamares_ml.ts | 206 ++++++++++++++++++++-------------------- lang/calamares_sv.ts | 66 ++++++------- lang/calamares_tr_TR.ts | 2 +- 6 files changed, 174 insertions(+), 174 deletions(-) diff --git a/lang/calamares_fr.ts b/lang/calamares_fr.ts index 47fd4fd9f..472e81f8d 100644 --- a/lang/calamares_fr.ts +++ b/lang/calamares_fr.ts @@ -3253,7 +3253,7 @@ Sortie Open release notes website - + Ouvrir le site des notes de publication diff --git a/lang/calamares_it_IT.ts b/lang/calamares_it_IT.ts index 1d860c7d0..136d33c3e 100644 --- a/lang/calamares_it_IT.ts +++ b/lang/calamares_it_IT.ts @@ -99,7 +99,7 @@ Reload Stylesheet - + Ricarica il foglio di stile @@ -210,7 +210,7 @@ Waiting for %n module(s). - + In attesa del(i) modulo(i) %n.In attesa del(i) modulo(i) %n. @@ -258,7 +258,7 @@ Would you like to paste the install log to the web? - + Vuoi incollare il log di installazione nel web? @@ -1148,7 +1148,7 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the setup program.</p></body></html> - + <html><head/><body><p>Quando questa casella è selezionata, il tuo computer verrà riavviato immediatamente quando clicchi su <span style="font-style:italic;">Finito</span> oppure chiudi il programma di setup.</p></body></html> @@ -1163,7 +1163,7 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno <h1>Setup Failed</h1><br/>%1 has not been set up on your computer.<br/>The error message was: %2. - + <h1>Installazione fallita</h1><br/>%1 non è stato installato sul tuo computer.<br/>Il messaggio di errore è: %2. @@ -1204,12 +1204,12 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno Format partition %1 (file system: %2, size: %3 MiB) on %4. - + Formatta la partitione %1 (file system: %2, dimensione: %3 MiB) su %4. Format <strong>%3MiB</strong> partition <strong>%1</strong> with file system <strong>%2</strong>. - + Formatta la partizione <strong>%1</strong> di dimensione <strong>%3MiB </strong> con il file system <strong>%2</strong>. @@ -1298,17 +1298,17 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno Could not create directories <code>%1</code>. - + Impossibile creare le cartelle <code>%1</code>. Could not open file <code>%1</code>. - + Impossibile aprire il file <code>%1</code>. Could not write to file <code>%1</code>. - + Impossibile scrivere sul file <code>%1</code>. @@ -1316,7 +1316,7 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno Creating initramfs with mkinitcpio. - + Sto creando initramfs con mkinitcpio. @@ -1324,7 +1324,7 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno Creating initramfs. - + Sto creando initramfs. @@ -1475,32 +1475,32 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno Shows the complete license text - + Mostra il testo completo della licenza Hide license text - + Nascondi il testo della licenza Show license agreement - + Mostra l'accordo di licenza Hide license agreement - + Nascondi l'accordo di licenza Opens the license agreement in a browser window. - + Apre l'accordo di licenza in una finestra del browser. <a href="%1">View license agreement</a> - + <a href="%1">Visualizza l'accordo di licenza</a> @@ -1556,7 +1556,7 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno No partitions are defined. - + Non è stata specificata alcuna partizione. @@ -2462,7 +2462,7 @@ Output: No description provided. - + Non è stata fornita alcuna descrizione. @@ -2564,7 +2564,7 @@ Output: Resize Filesystem Job - + Operazione di ridimensionamento del Filesystem @@ -2574,7 +2574,7 @@ Output: The file-system resize job has an invalid configuration and will not run. - + L'operazione di ridimensionamento del file-system ha una configurazione non valida e non verrà effettuata. @@ -2622,12 +2622,12 @@ Output: The filesystem %1 must be resized, but cannot. - + Il filesystem %1 deve essere ridimensionato, ma non è possibile farlo. The device %1 must be resized, but cannot - + Il dispositivo %1 deve essere ridimensionato, non è possibile farlo @@ -2645,7 +2645,7 @@ Output: Resizing %2MiB partition %1 to %3MiB. - + Sto ridimensionando la partizione %1 di dimensione %2MiB a %3MiB. @@ -2667,12 +2667,12 @@ Output: Resize volume group named %1 from %2 to %3. - + Ridimensiona il gruppo di volumi con nome %1 da %2 a %3. Resize volume group named <strong>%1</strong> from <strong>%2</strong> to <strong>%3</strong>. - + Ridimensiona il gruppo di volumi con nome <strong>%1</strong> da <strong>%2</strong> a <strong>%3</strong>. @@ -2685,7 +2685,7 @@ Output: This computer does not satisfy the minimum requirements for setting up %1.<br/>Setup cannot continue. <a href="#details">Details...</a> - + Questo computer non soddisfa i requisiti minimi per l'installazione di %1.<br/>L'installazione non può continuare. <a href="#details">Dettagli...</a> @@ -2695,7 +2695,7 @@ Output: This computer does not satisfy some of the recommended requirements for setting up %1.<br/>Setup can continue, but some features might be disabled. - + Questo computer non soddisfa alcuni requisiti raccomandati per l'installazione di %1.<br/>L'installazione può continuare, ma alcune funzionalità potrebbero essere disabilitate. @@ -3230,17 +3230,17 @@ Output: Open donations website - + Apri il sito web per le donazioni &Donate - + &Donazioni Open help and support website - + Apri il sito web per l'aiuto ed il supporto @@ -3250,7 +3250,7 @@ Output: Open release notes website - + Apri il sito web delle note di rilascio @@ -3285,12 +3285,12 @@ Output: <h1>Welcome to the Calamares setup program for %1.</h1> - + <h1>Benvenuto nel programma di installazione Calamares di %1.</h1> <h1>Welcome to %1 setup.</h1> - + <h1>Benvenuto nell'installazione di %1.</h1> diff --git a/lang/calamares_ja.ts b/lang/calamares_ja.ts index 58d127397..29dec7ca4 100644 --- a/lang/calamares_ja.ts +++ b/lang/calamares_ja.ts @@ -1165,7 +1165,7 @@ The installer will quit and all changes will be lost. <h1>Setup Failed</h1><br/>%1 has not been set up on your computer.<br/>The error message was: %2. - <h1>セットアップに失敗しました。</h1><br/>%1 はコンピュータにセットアップされていません。<br/>エラーメッセージは次のとおりです: %2 + <h1>セットアップに失敗しました。</h1><br/>%1 はコンピュータにセットアップされていません。<br/>エラーメッセージ: %2 diff --git a/lang/calamares_ml.ts b/lang/calamares_ml.ts index c26f8f28d..7941eaaa2 100644 --- a/lang/calamares_ml.ts +++ b/lang/calamares_ml.ts @@ -135,7 +135,7 @@ Programmed job failure was explicitly requested. - + പ്രോഗ്രാം ചെയ്യപ്പെട്ട ജോലിയുടെ പരാജയം പ്രത്യേകമായി ആവശ്യപ്പെട്ടിരുന്നു. @@ -648,12 +648,12 @@ The installer will quit and all changes will be lost. The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. - + കമാൻഡ് ഹോസ്റ്റ് എൻവയോൺമെന്റിൽ പ്രവർത്തിക്കുന്നു, റൂട്ട് പാത്ത് അറിയേണ്ടതുണ്ട്, പക്ഷേ rootMountPoint നിർവചിച്ചിട്ടില്ല. The command needs to know the user's name, but no username is defined. - + കമാൻഡിന് ഉപയോക്താവിന്റെ പേര് അറിയേണ്ടതുണ്ട്,എന്നാൽ ഉപയോക്തൃനാമമൊന്നും നിർവചിച്ചിട്ടില്ല. @@ -661,7 +661,7 @@ The installer will quit and all changes will be lost. Contextual Processes Job - + സാന്ദർഭിക പ്രക്രിയകൾ ജോലി @@ -932,7 +932,7 @@ The installer will quit and all changes will be lost. The type of <strong>partition table</strong> on the selected storage device.<br><br>The only way to change the partition table type is to erase and recreate the partition table from scratch, which destroys all data on the storage device.<br>This installer will keep the current partition table unless you explicitly choose otherwise.<br>If unsure, on modern systems GPT is preferred. - + തിരഞ്ഞെടുത്ത സ്റ്റോറേജ് ഉപകരണത്തിലെ <strong>പാർട്ടീഷൻ ടേബിളിന്റെ</strong>തരം.<br><br>പാർട്ടീഷൻ ടേബിൾ തരം മാറ്റാനുള്ള ഒരേയൊരു മാർഗ്ഗം പാർട്ടീഷൻ ടേബിൾ ആദ്യം മുതൽ മായ്ച്ചുകളയുക എന്നതാണ്,ഇത് സംഭരണ ഉപകരണത്തിലെ എല്ലാ ഡാറ്റയും നശിപ്പിക്കുന്നു.<br>നിങ്ങൾ വ്യക്തമായി തിരഞ്ഞെടുത്തിട്ടില്ലെങ്കിൽ ഈ ഇൻസ്റ്റാളർ നിലവിലെ പാർട്ടീഷൻ ടേബിൾ സൂക്ഷിക്കും.<br>ഉറപ്പില്ലെങ്കിൽ, ആധുനിക സിസ്റ്റങ്ങളിൽ ജിപിടിയാണ് ശുപാർശ ചെയ്യുന്നത്. @@ -942,7 +942,7 @@ The installer will quit and all changes will be lost. This is a <strong>loop</strong> device.<br><br>It is a pseudo-device with no partition table that makes a file accessible as a block device. This kind of setup usually only contains a single filesystem. - + ഇതൊരു <strong>ലൂപ്പ്</strong> ഉപകരണമാണ്.<br><br>ഒരു ഫയലിന്റെ ഒരു ബ്ലോക്ക് ഉപകരണമാക്കി ലഭ്യമാക്കുന്ന പാർട്ടീഷൻ ടേബിളില്ലാത്ത ഒരു കൃത്രിമ-ഉപകരണമാണിത്. ഇത്തരത്തിലുള്ള ക്രമീകരണത്തിൽ സാധാരണ ഒരൊറ്റ ഫയൽ സിസ്റ്റം മാത്രമേ കാണൂ. @@ -1344,7 +1344,7 @@ The installer will quit and all changes will be lost. Executing script: &nbsp;<code>%1</code> - + സ്ക്രിപ്റ്റ് നിർവ്വഹിക്കുന്നു:&nbsp;<code>%1</code> @@ -1386,7 +1386,7 @@ The installer will quit and all changes will be lost. The system locale setting affects the language and character set for some command line user interface elements.<br/>The current setting is <strong>%1</strong>. - + സിസ്റ്റം ലൊക്കേൽ ഭാഷയും, കമാൻഡ് ലൈൻ സമ്പർക്കമുഖഘടകങ്ങളുടെ അക്ഷരക്കൂട്ടങ്ങളേയും സ്വാധീനിക്കും. <br/>നിലവിലുള്ള ക്രമീകരണം <strong>%1</strong> ആണ്. @@ -1414,22 +1414,22 @@ The installer will quit and all changes will be lost. <h1>License Agreement</h1>This setup procedure will install proprietary software that is subject to licensing terms. - + <h1>ലൈസൻസ് ഉടമ്പടി</h1>ഈ സജ്ജീകരണ നടപടിക്രമം ലൈസൻസിംഗ് നിബന്ധനകൾക്ക് വിധേയമായ കുത്തക സോഫ്റ്റ്വെയർ ഇൻസ്റ്റാൾ ചെയ്യും. Please review the End User License Agreements (EULAs) above.<br/>If you do not agree with the terms, the setup procedure cannot continue. - + മുകളിലുള്ള അന്തിമ ഉപയോക്തൃ ലൈസൻസ് കരാറുകൾ (EULAs) അവലോകനം ചെയ്യുക.<br/>നിങ്ങൾ നിബന്ധനകളോട് യോജിക്കുന്നില്ലെങ്കിൽ, സജ്ജീകരണ നടപടിക്രമം തുടരാനാവില്ല. <h1>License Agreement</h1>This setup procedure can install proprietary software that is subject to licensing terms in order to provide additional features and enhance the user experience. - + <h1>ലൈസൻസ് ഉടമ്പടി</h1>അധിക സവിശേഷതകൾ നൽകുന്നതിനും ഉപയോക്തൃ അനുഭവം മെച്ചപ്പെടുത്തുന്നതിനും ഈ സജ്ജീകരണ നടപടിക്രമത്തിന് ലൈസൻസിംഗ് നിബന്ധനകൾക്ക് വിധേയമായ കുത്തക സോഫ്റ്റ്വെയർ ഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയും. Please review the End User License Agreements (EULAs) above.<br/>If you do not agree with the terms, proprietary software will not be installed, and open source alternatives will be used instead. - + മുകളിലുള്ള അന്തിമ ഉപയോക്തൃ ലൈസൻസ് കരാറുകൾ (EULAs) അവലോകനം ചെയ്യുക.<br/>നിങ്ങൾ നിബന്ധനകളോട് യോജിക്കുന്നില്ലെങ്കിൽ, പ്രൊപ്രൈറ്ററി സോഫ്റ്റ്വെയർ ഇൻസ്റ്റാൾ ചെയ്യില്ല, പകരം ഓപ്പൺ സോഴ്‌സ് ഇതരമാർഗങ്ങൾ ഉപയോഗിക്കും. @@ -1452,27 +1452,27 @@ The installer will quit and all changes will be lost. <strong>%1 graphics driver</strong><br/><font color="Grey">by %2</font> %1 is usually a vendor name, example: Nvidia graphics driver - + <strong>%1 ഗ്രാഫിക്സ് ഡ്രൈവർ</strong><br/><font color="Grey">by %2</font> <strong>%1 browser plugin</strong><br/><font color="Grey">by %2</font> - + <strong>%1 ബ്രൌസർ പ്ലഗിൻ</strong><br/><font color="Grey">by %2</font> <strong>%1 codec</strong><br/><font color="Grey">by %2</font> - + <strong>%1 കോഡെക് </strong><br/><font color="Grey">by %2</font> <strong>%1 package</strong><br/><font color="Grey">by %2</font> - + <strong>%1 പാക്കേജ് </strong><br/><font color="Grey">by %2</font> <strong>%1</strong><br/><font color="Grey">by %2</font> - + <strong>%1</strong><br/><font color="Grey">by %2</font> @@ -1624,7 +1624,7 @@ The installer will quit and all changes will be lost. Ba&tch: - + കൂട്ടം (&t): @@ -1634,7 +1634,7 @@ The installer will quit and all changes will be lost. <html><head/><body><h1>OEM Configuration</h1><p>Calamares will use OEM settings while configuring the target system.</p></body></html> - + <html><head/><body><h1>OEM ക്രമീകരണം</h1><p>കലാമരേസ് ലക്ഷ്യ സിസ്റ്റം ക്രമീകരിക്കുമ്പോൾ OEM ക്രമീകരണങ്ങൾ ഉപയോഗിക്കും.</p></body></html> @@ -1647,7 +1647,7 @@ The installer will quit and all changes will be lost. Set the OEM Batch Identifier to <code>%1</code>. - + OEM ബാച്ച് ഐഡന്റിഫയർ <code>%1</code> ആയി ക്രമീകരിക്കുക. @@ -1770,7 +1770,7 @@ The installer will quit and all changes will be lost. The password contains less than %1 character classes - + പാസ്‌വേഡിൽ പ്രതീക ക്ലാസുകൾ %1 ൽ കുറവാണ് @@ -1800,12 +1800,12 @@ The installer will quit and all changes will be lost. The password contains monotonic sequence longer than %1 characters - + പാസ്‌വേഡിൽ %1 പ്രതീകങ്ങളേക്കാൾ ദൈർഘ്യമുള്ള മോണോടോണിക് ശ്രേണി അടങ്ങിയിരിക്കുന്നു The password contains too long of a monotonic character sequence - + പാസ്‌വേഡിൽ വളരെ ദൈർഘ്യമുള്ള ഒരു മോണോടോണിക് പ്രതീക ശ്രേണിയുണ്ട് @@ -1845,7 +1845,7 @@ The installer will quit and all changes will be lost. Bad integer value of setting - %1 - + ക്രമീകരണത്തിന്റെ ശരിയല്ലാത്ത സംഖ്യാമൂല്യം - %1 @@ -1987,7 +1987,7 @@ The installer will quit and all changes will be lost. <small>This name will be used if you make the computer visible to others on a network.</small> - + <small>നിങ്ങൾ ഒരു നെറ്റ്‌വർക്കിൽ കമ്പ്യൂട്ടർ മറ്റുള്ളവർക്ക് ദൃശ്യമാക്കുകയാണെങ്കിൽ ഈ പേര് ഉപയോഗിക്കും.</small> @@ -2007,7 +2007,7 @@ The installer will quit and all changes will be lost. <small>Enter the same password twice, so that it can be checked for typing errors.</small> - + <small>ഒരേ പാസ്‌വേഡ് രണ്ടുതവണ നൽകുക, അതുവഴി ടൈപ്പിംഗ് പിശകുകൾ പരിശോധിക്കാൻ കഴിയും.</small> @@ -2164,7 +2164,7 @@ The installer will quit and all changes will be lost. The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead. - + %1 ലെ പാർട്ടീഷൻ പട്ടികയിൽ ഇതിനകം %2 പ്രാഥമിക പാർട്ടീഷനുകൾ ഉണ്ട്,ഇനി ഒന്നും ചേർക്കാൻ കഴിയില്ല. പകരം ഒരു പ്രാഥമിക പാർട്ടീഷൻ നീക്കംചെയ്‌ത് എക്സ്ടെൻഡഡ്‌ പാർട്ടീഷൻ ചേർക്കുക. @@ -2182,7 +2182,7 @@ The installer will quit and all changes will be lost. Install %1 <strong>alongside</strong> another operating system. - + മറ്റൊരു ഓപ്പറേറ്റിംഗ് സിസ്റ്റത്തിനൊപ്പം %1 ഇൻസ്റ്റാൾ ചെയ്യുക. @@ -2197,12 +2197,12 @@ The installer will quit and all changes will be lost. <strong>Manual</strong> partitioning. - + <strong>സ്വമേധയാ</strong> ഉള്ള പാർട്ടീഷനിങ്. Install %1 <strong>alongside</strong> another operating system on disk <strong>%2</strong> (%3). - + %2 (%3) ഡിസ്കിൽ മറ്റൊരു ഓപ്പറേറ്റിംഗ് സിസ്റ്റത്തിനൊപ്പം %1 ഇൻസ്റ്റാൾ ചെയ്യുക. @@ -2262,7 +2262,7 @@ The installer will quit and all changes will be lost. A separate boot partition was set up together with an encrypted root partition, but the boot partition is not encrypted.<br/><br/>There are security concerns with this kind of setup, because important system files are kept on an unencrypted partition.<br/>You may continue if you wish, but filesystem unlocking will happen later during system startup.<br/>To encrypt the boot partition, go back and recreate it, selecting <strong>Encrypt</strong> in the partition creation window. - + എൻക്രിപ്റ്റ് ചെയ്ത ഒരു റൂട്ട് പാർട്ടീഷനോടൊപ്പം ഒരു വേർപെടുത്തിയ ബൂട്ട് പാർട്ടീഷനും ക്രമീകരിക്കപ്പെട്ടിരുന്നു, എന്നാൽ ബൂട്ട് പാർട്ടീഷൻ എൻക്രിപ്റ്റ് ചെയ്യപ്പെട്ടതല്ല.<br/><br/>ഇത്തരം സജ്ജീകരണത്തിന്റെ സുരക്ഷ ഉത്കണ്ഠാജനകമാണ്, എന്തെന്നാൽ പ്രധാനപ്പെട്ട സിസ്റ്റം ഫയലുകൾ ഒരു എൻക്രിപ്റ്റ് ചെയ്യപ്പെടാത്ത പാർട്ടീഷനിലാണ് സൂക്ഷിച്ചിട്ടുള്ളത്.<br/> താങ്കൾക്ക് വേണമെങ്കിൽ തുടരാം, പക്ഷേ ഫയൽ സിസ്റ്റം തുറക്കൽ സിസ്റ്റം ആരംഭപ്രക്രിയയിൽ വൈകിയേ സംഭവിക്കൂ.<br/>ബൂട്ട് പാർട്ടീഷൻ എൻക്രിപ്റ്റ് ചെയ്യാനായി, തിരിച്ചു പോയി പാർട്ടീഷൻ നിർമ്മാണ ജാലകത്തിൽ <strong>എൻക്രിപ്റ്റ്</strong> തിരഞ്ഞെടുത്തുകൊണ്ട് അത് വീണ്ടും നിർമ്മിക്കുക. @@ -2280,13 +2280,13 @@ The installer will quit and all changes will be lost. Plasma Look-and-Feel Job - + പ്ലാസ്മ കെട്ടും മട്ടും ജോലി Could not select KDE Plasma Look-and-Feel package - + കെഡിഇ പ്ലാസ്മ കെട്ടും മട്ടും പാക്കേജ് തിരഞ്ഞെടുക്കാനായില്ല @@ -2299,12 +2299,12 @@ The installer will quit and all changes will be lost. Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is set up. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. - + കെ‌ഡി‌ഇ പ്ലാസ്മ ഡെസ്‌ക്‌ടോപ്പിനായി ഒരു കെട്ടും മട്ടും തിരഞ്ഞെടുക്കുക.നിങ്ങൾക്ക് ഈ ഘട്ടം ഇപ്പോൾ ഒഴിവാക്കി സിസ്റ്റം ഇൻസ്റ്റാൾ ചെയ്തതിനു ശേഷവും കെട്ടും മട്ടും ക്രമീരകരിക്കാൻ കഴിയും.ഒരു കെട്ടും മട്ടും തിരഞ്ഞെടുക്കലിൽ ക്ലിക്കുചെയ്യുന്നത് ആ കെട്ടും മട്ടിന്റെയും തത്സമയ പ്രിവ്യൂ നൽകും. Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is installed. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. - + കെ‌ഡി‌ഇ പ്ലാസ്മ ഡെസ്‌ക്‌ടോപ്പിനായി ഒരു കെട്ടും മട്ടും തിരഞ്ഞെടുക്കുക.നിങ്ങൾക്ക് ഈ ഘട്ടം ഇപ്പോൾ ഒഴിവാക്കി സിസ്റ്റം ഇൻസ്റ്റാൾ ചെയ്തതിനു ശേഷവും കെട്ടും മട്ടും ക്രമീരകരിക്കാൻ കഴിയും @@ -2312,7 +2312,7 @@ The installer will quit and all changes will be lost. Look-and-Feel - + കെട്ടും മട്ടും @@ -2354,7 +2354,7 @@ Output: External command crashed. - + ബാഹ്യമായ ആജ്ഞ തകർന്നു. @@ -2364,12 +2364,12 @@ Output: External command failed to start. - + ബാഹ്യമായ ആജ്ഞ ആരംഭിക്കുന്നതിൽ പരാജയപ്പെട്ടു. Command <i>%1</i> failed to start. - + <i>%1</i>ആജ്ഞ ആരംഭിക്കുന്നതിൽ പരാജയപ്പെട്ടു. @@ -2379,27 +2379,27 @@ Output: Bad parameters for process job call. - + പ്രക്രിയ ജോലി വിളിയ്ക്ക് ശരിയല്ലാത്ത പരാമീറ്ററുകൾ. External command failed to finish. - + ബാഹ്യമായ ആജ്ഞ പൂർത്തിയാവുന്നതിൽ പരാജയപ്പെട്ടു. Command <i>%1</i> failed to finish in %2 seconds. - + ആജ്ഞ <i>%1</i> %2 സെക്കൻഡുകൾക്കുള്ളിൽ പൂർത്തിയാവുന്നതിൽ പരാജയപ്പെട്ടു. External command finished with errors. - + ബാഹ്യമായ ആജ്ഞ പിഴവുകളോട് കൂടീ പൂർത്തിയായി. Command <i>%1</i> finished with exit code %2. - + ആജ്ഞ <i>%1</i> എക്സിറ്റ് കോഡ് %2ഓട് കൂടി പൂർത്തിയായി. @@ -2423,7 +2423,7 @@ Output: extended - + വിസ്തൃതമായത് @@ -2566,7 +2566,7 @@ Output: Resize Filesystem Job - + ഫയൽ സിസ്റ്റത്തിന്റെ വലുപ്പം മാറ്റുന്ന ജോലി @@ -2576,19 +2576,19 @@ Output: The file-system resize job has an invalid configuration and will not run. - + ഫയൽ സിസ്റ്റം വലുപ്പം മാറ്റുന്ന ജോലിയിൽ അസാധുവായ ക്രമീകരണം ഉണ്ട്, അത് പ്രവർത്തിക്കില്ല. KPMCore not Available - + KPMCore ലഭ്യമല്ല Calamares cannot start KPMCore for the file-system resize job. - + ഫയൽ സിസ്റ്റം വലുപ്പം മാറ്റുന്നതിനുള്ള ജോലിക്കായി കാലാമറസിന് KPMCore ആരംഭിക്കാൻ കഴിയില്ല. @@ -2597,39 +2597,39 @@ Output: Resize Failed - + വലുപ്പം മാറ്റുന്നത് പരാജയപ്പെട്ടു The filesystem %1 could not be found in this system, and cannot be resized. - + ഫയൽ സിസ്റ്റം %1 ഈ സിസ്റ്റത്തിൽ കണ്ടെത്താനായില്ല, അതിനാൽ അതിന്റെ വലുപ്പം മാറ്റാനാവില്ല. The device %1 could not be found in this system, and cannot be resized. - + ഉപകരണം %1 ഈ സിസ്റ്റത്തിൽ കണ്ടെത്താനായില്ല, അതിനാൽ അതിന്റെ വലുപ്പം മാറ്റാനാവില്ല. The filesystem %1 cannot be resized. - + %1 എന്ന ഫയൽസിസ്റ്റത്തിന്റെ വലുപ്പം മാറ്റാൻ കഴിയില്ല. The device %1 cannot be resized. - + %1 ഉപകരണത്തിന്റെ വലുപ്പം മാറ്റാൻ കഴിയില്ല. The filesystem %1 must be resized, but cannot. - + %1 എന്ന ഫയൽസിസ്റ്റത്തിന്റെ വലുപ്പം മാറ്റണം, പക്ഷേ കഴിയില്ല. The device %1 must be resized, but cannot - + %1 ഉപകരണത്തിന്റെ വലുപ്പം മാറ്റണം, പക്ഷേ കഴിയില്ല @@ -2637,22 +2637,22 @@ Output: Resize partition %1. - + %1 പാർട്ടീഷന്റെ വലുപ്പം മാറ്റുക. Resize <strong>%2MiB</strong> partition <strong>%1</strong> to <strong>%3MiB</strong>. - + <strong>%1</strong> എന്ന <strong>%2MiB</strong> പാർട്ടീഷന്റെ വലുപ്പം <strong>%3Mib</strong>യിലേക്ക് മാറ്റുക. Resizing %2MiB partition %1 to %3MiB. - + %1 എന്ന %2MiB പാർട്ടീഷന്റെ വലുപ്പം %3Mibയിലേക്ക് മാറ്റുന്നു. The installer failed to resize partition %1 on disk '%2'. - + '%2' ഡിസ്കിലുള്ള %1 പാർട്ടീഷന്റെ വലുപ്പം മാറ്റുന്നതിൽ ഇൻസ്റ്റാളർ പരാജയപ്പെട്ടു @@ -2669,17 +2669,17 @@ Output: Resize volume group named %1 from %2 to %3. - + %1 എന്ന് പേരുള്ള വോള്യം ഗ്രൂപ്പിന്റെ വലുപ്പം %2ൽ നിന്നും %3ലേക്ക് മാറ്റുക. Resize volume group named <strong>%1</strong> from <strong>%2</strong> to <strong>%3</strong>. - + <strong>%1</strong> എന്ന് പേരുള്ള വോള്യം ഗ്രൂപ്പിന്റെ വലുപ്പം <strong>%2</strong>ൽ നിന്നും <strong>%3</strong>ലേക്ക് മാറ്റുക. The installer failed to resize a volume group named '%1'. - + '%1' എന്ന് പേരുള്ള ഒരു വോള്യം ഗ്രൂപ്പിന്റെ വലുപ്പം മാറ്റുന്നതിൽ ഇൻസ്റ്റാളർ പരാജയപ്പെട്ടു. @@ -2712,7 +2712,7 @@ Output: For best results, please ensure that this computer: - + മികച്ച ഫലങ്ങൾക്കായി ഈ കമ്പ്യൂട്ടർ താഴെപ്പറയുന്നവ നിറവേറ്റുന്നു എന്നുറപ്പുവരുത്തുക: @@ -2760,7 +2760,7 @@ Output: Cannot write hostname to target system - + ടാർഗെറ്റ് സിസ്റ്റത്തിലേക്ക് ഹോസ്റ്റ്നാമം എഴുതാൻ കഴിയില്ല @@ -2768,12 +2768,12 @@ Output: Set keyboard model to %1, layout to %2-%3 - + കീബോർഡ് മാതൃക %1 ആയി ക്രമീകരിക്കുക, രൂപരേഖ %2-%3 Failed to write keyboard configuration for the virtual console. - + വിർച്വൽ കൺസോളിനായുള്ള കീബോർഡ് ക്രമീകരണം എഴുതുന്നതിൽ പരാജയപ്പെട്ടു. @@ -2785,12 +2785,12 @@ Output: Failed to write keyboard configuration for X11. - + X11 നായി കീബോർഡ് കോൺഫിഗറേഷൻ എഴുതുന്നതിൽ പരാജയപ്പെട്ടു. Failed to write keyboard configuration to existing /etc/default directory. - + നിലവിലുള്ള /etc/default ഡയറക്ടറിയിലേക്ക് കീബോർഡ് കോൺഫിഗറേഷൻ എഴുതുന്നതിൽ പരാജയപ്പെട്ടു. @@ -2823,17 +2823,17 @@ Output: Flag %1MiB <strong>%2</strong> partition as <strong>%3</strong>. - + %1MiB <strong>%2</strong> പാർട്ടീഷൻ <strong>%3</strong> ആയി ഫ്ലാഗ് ചെയ്യുക. Clearing flags on %1MiB <strong>%2</strong> partition. - + ഫ്ലാഗുകൾ %1MiB <strong>%2</strong> പാർട്ടീഷനിൽ നിർമ്മിക്കുന്നു. Setting flags <strong>%3</strong> on %1MiB <strong>%2</strong> partition. - + <strong>%3</strong> ഫ്ലാഗുകൾ %1MiB <strong>%2</strong> പാർട്ടീഷനിൽ ക്രമീകരിക്കുന്നു. @@ -2843,12 +2843,12 @@ Output: Flag partition <strong>%1</strong> as <strong>%2</strong>. - + <strong>%1</strong> പാർട്ടീഷനെ <strong>%2</strong> ആയി ഫ്ലാഗ് ചെയ്യുക Flag new partition as <strong>%1</strong>. - + പുതിയ പാർട്ടീഷൻ <strong>%1 </strong>ആയി ഫ്ലാഗുചെയ്യുക. @@ -2863,12 +2863,12 @@ Output: Setting flags <strong>%2</strong> on partition <strong>%1</strong>. - + <strong>%2</strong> ഫ്ലാഗുകൾ <strong>%1</strong> പാർട്ടീഷനിൽ ക്രമീകരിക്കുക. Setting flags <strong>%1</strong> on new partition. - + <strong>%1</strong> ഫ്ലാഗുകൾ പുതിയ പാർട്ടീഷനിൽ ക്രമീകരിക്കുക. @@ -2891,12 +2891,12 @@ Output: Bad destination system path. - + ലക്ഷ്യത്തിന്റെ സിസ്റ്റം പാത്ത് തെറ്റാണ്. rootMountPoint is %1 - + rootMountPoint %1 ആണ് @@ -2906,7 +2906,7 @@ Output: passwd terminated with error code %1. - + passwd പിഴവ് കോഡ്‌ %1 ഓട് കൂടീ അവസാനിച്ചു. @@ -2916,7 +2916,7 @@ Output: usermod terminated with error code %1. - + usermod പിഴവ് കോഡ്‌ %1 ഓട് കൂടീ അവസാനിച്ചു. @@ -2924,17 +2924,17 @@ Output: Set timezone to %1/%2 - + %1%2 എന്നതിലേക്ക് സമയപദ്ധതി ക്രമീകരിക്കുക Cannot access selected timezone path. - + തിരഞ്ഞെടുത്ത സമയപദ്ധതി പാത്ത് ലഭ്യമല്ല. Bad path: %1 - + മോശമായ പാത്ത്: %1 @@ -2944,7 +2944,7 @@ Output: Link creation failed, target: %1; link name: %2 - + കണ്ണി ഉണ്ടാക്കൽ പരാജയപ്പെട്ടു, ലക്ഷ്യം: %1, കണ്ണിയുടെ പേര്: %2 @@ -2962,7 +2962,7 @@ Output: Shell Processes Job - + ഷെൽ പ്രക്രിയകൾ ജോലി @@ -2971,7 +2971,7 @@ Output: %L1 / %L2 slide counter, %1 of %2 (numeric) - + %L1 / %L2 @@ -2984,7 +2984,7 @@ Output: This is an overview of what will happen once you start the install procedure. - + നിങ്ങൾ ഇൻസ്റ്റാൾ നടപടിക്രമങ്ങൾ ആരംഭിച്ചുകഴിഞ്ഞാൽ എന്ത് സംഭവിക്കും എന്നതിന്റെ ഒരു അവലോകനമാണിത്. @@ -3010,12 +3010,12 @@ Output: Internal error in install-tracking. - + ഇൻസ്റ്റാൾ-പിന്തുടരുന്നതിൽ ആന്തരികമായ പിഴവ്. HTTP request timed out. - + HTTP അപേക്ഷയുടെ സമയപരിധി കഴിഞ്ഞു. @@ -3023,28 +3023,28 @@ Output: Machine feedback - + ഉപകരണത്തിൽ നിന്നുള്ള പ്രതികരണം Configuring machine feedback. - + ഉപകരണത്തിൽ നിന്നുള്ള പ്രതികരണം ക്രമീകരിക്കുന്നു. Error in machine feedback configuration. - + ഉപകരണത്തിൽ നിന്നുള്ള പ്രതികരണത്തിന്റെ ക്രമീകരണത്തിൽ പിഴവ്. Could not configure machine feedback correctly, script error %1. - + ഉപകരണത്തിൽ നിന്നുള്ള പ്രതികരണം ശരിയായി ക്രമീകരിക്കാനായില്ല. സ്ക്രിപ്റ്റ് പിഴവ് %1. Could not configure machine feedback correctly, Calamares error %1. - + ഉപകരണത്തിൽ നിന്നുള്ള പ്രതികരണം ശരിയായി ക്രമീകരിക്കാനായില്ല. കലാമാരേസ് പിഴവ് %1. @@ -3057,22 +3057,22 @@ Output: Placeholder - + പ്ലേസ്‌ഹോൾഡർ <html><head/><body><p>By selecting this, you will send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html> - + <html><head/><body><p>ഇത് തിരഞ്ഞെടുക്കുന്നതിലൂടെ, നിങ്ങളുടെ ഇൻസ്റ്റാളേഷനെക്കുറിച്ച് <span style=" font-weight:600;">ഒരു വിവരവും നിങ്ങൾ അയയ്‌ക്കില്ല.</span></p></body></html> <html><head/><body><p><a href="placeholder"><span style=" text-decoration: underline; color:#2980b9;">Click here for more information about user feedback</span></a></p></body></html> - + <html><head/><body><p><a href="placeholder"><span style=" text-decoration: underline; color:#2980b9;">ഉപയോക്തൃ ഫീഡ്‌ബാക്കിനെക്കുറിച്ചുള്ള കൂടുതൽ വിവരങ്ങൾക്ക് ഇവിടെ ക്ലിക്കുചെയ്യുക</span></a></p></body></html> Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with the last two options below), get continuous information about preferred applications. To see what will be sent, please click the help icon next to each area. - + എത്ര ഉപയോക്താക്കളുണ്ട് ,ഏത് ഹാർഡ്‌വെയറിലാണ് %1 ഇൻസ്റ്റാൾ ചെയ്യുന്നത് (ചുവടെയുള്ള അവസാന രണ്ടു ഓപ്ഷനുകൾക്കൊപ്പം) കൂടാതെ നിങ്ങൾ മുന്ഗണന നൽകുന്ന പ്രയോഗങ്ങളെക്കുറിച്ചുള്ള വിവരങ്ങൾ നേടുന്നതിന് %1 ഇൻസ്റ്റാൾ ട്രാക്കിംഗ് സഹായിക്കുന്നു.എന്താണ് അയയ്‌ക്കുന്നതെന്ന് കാണാൻ, ഓരോ ഭാഗത്തിനും അടുത്തുള്ള സഹായ ഐക്കണിൽ ക്ലിക്കുചെയ്യുക. @@ -3082,7 +3082,7 @@ Output: By selecting this you will <b>periodically</b> send information about your installation, hardware and applications, to %1. - + ഇത് തിരഞ്ഞെടുക്കുന്നതിലൂടെ താങ്കൾ <b>ഇടയ്ക്കിടെ</b>താങ്കളുടെ ഇൻസ്റ്റളേഷനെയും ഹാർഡ്‌വെയറിനെയും പ്രയോഗങ്ങളേയും പറ്റിയുള്ള വിവരങ്ങൾ %1ന് അയച്ചുകൊടുക്കും. @@ -3173,7 +3173,7 @@ Output: List of Physical Volumes - + ഫിസിക്കൽ വോള്യങ്ങളുടെ പട്ടിക @@ -3188,7 +3188,7 @@ Output: Physical Extent Size: - + ഫിസിക്കൽ എക്സ്റ്റന്റ് വലുപ്പം: @@ -3213,7 +3213,7 @@ Output: Quantity of LVs: - + LVകളുടെ അളവ്: @@ -3307,7 +3307,7 @@ Output: <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017-2019 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Thanks to <a href="https://calamares.io/team/">the Calamares team</a> and the <a href="https://www.transifex.com/calamares/calamares/">Calamares translators team</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. - + <h1>%1</h1><br/><strong>%2<br/>%3 ന്</strong><br/><br/>പകർപ്പവകാശം 2015-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>പകർപ്പവകാശം 2018-2019 Adriaan de Groot &lt;groot@kde.org&gt;<br/><a href="https://calamares.io/team/">കലാമരേസ് ടീമിനും</a><a href="https://www.transifex.com/calamares/calamares/">കലാമരേസ് പരിഭാഷാ ടീമിനും</a> നന്ദി.<br/><br/><a href="https://calamares.io/">കലാമരേസ്</a>വികസനം <br/><a href="http://www.blue-systems.com/">Blue Systems</a>- Liberating Software സ്പോൺസർ ചെയ്യുന്നതാണ്. diff --git a/lang/calamares_sv.ts b/lang/calamares_sv.ts index 57892470b..f84f4f8d0 100644 --- a/lang/calamares_sv.ts +++ b/lang/calamares_sv.ts @@ -4,17 +4,17 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - Systemets <strong>uppstartsmiljö</strong>.<br><br>Äldre x86-system stödjer endast <strong>BIOS</strong>.<br>Moderna system stödjer vanligen <strong>EFI</strong>, men kan också vara i kompabilitetsläge för BIOS. + Systemets <strong>startmiljö</strong>.<br><br>Äldre x86-system stöder endast <strong>BIOS</strong>.<br>Moderna system stöder vanligen <strong>EFI</strong>, men kan också vara i kompatibilitetsläge för BIOS. This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. - Detta system startades med en <strong>EFI-miljö</strong>.<br><br>För att ställa in uppstart från en EFI-miljö måste en uppstartsladdare användas, t.ex. <strong>GRUB</strong> eller <strong>systemd-boot</strong> eller en <strong>EFI-systempartition</strong>. Detta sker automatiskt, såvida du inte väljer att partitionera manuellt. Då måste du själv installera en uppstartsladdare. + Detta system startades med en <strong>EFI-miljö</strong>.<br><br>För att ställa in start från en EFI-miljö måste en starthanterare användas, t.ex. <strong>GRUB</strong> eller <strong>systemd-boot</strong> på en <strong>EFI-systempartition</strong>. Detta sker automatiskt, såvida du inte väljer att partitionera manuellt. Då måste du själv installera en starthanterare. This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. - Detta system startades med en <strong>BIOS-miljö</strong>. <br><br>För att ställa in uppstart från en BIOS-miljö måste en uppstartsladdare som t.ex. <strong>GRUB</strong> installeras, antingen i början av en partition eller på <strong>huvudstartsektorn (MBR)</strong> i början av partitionstabellen. Detta sker automatiskt, såvida du inte väljer manuell partitionering. Då måste du själv installera en uppstartsladdare. + Detta system startades med en <strong>BIOS-miljö</strong>. <br><br>För att ställa in start från en BIOS-miljö måste en starthanterare som t.ex. <strong>GRUB</strong> installeras, antingen i början av en partition eller på <strong>huvudstartsektorn (MBR)</strong> i början av partitionstabellen. Detta sker automatiskt, såvida du inte väljer manuell partitionering. Då måste du själv installera en starthanterare. @@ -27,7 +27,7 @@ Boot Partition - Uppstartspartition + Startpartition @@ -37,7 +37,7 @@ Do not install a boot loader - Installera inte en uppstartsladdare + Installera inte någon starthanterare @@ -210,12 +210,12 @@ Waiting for %n module(s). - + Väntar på %n modul(er).Väntar på %n modul(er). (%n second(s)) - + (%n sekund(er))(%n sekund(er)) @@ -273,7 +273,7 @@ Calamares Initialization Failed - + Initieringen av Calamares misslyckades @@ -283,7 +283,7 @@ <br/>The following modules could not be loaded: - + <br/>Följande moduler kunde inte hämtas: @@ -363,7 +363,7 @@ Alla ändringar kommer att gå förlorade. The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> - %1-installeraren är på väg att göra ändringar för att installera %2.<br/><strong>Du kommer inte att kunna ångra dessa ändringar!strong> + %1-installeraren är på väg att göra ändringar för att installera %2.<br/><strong>Du kommer inte att kunna ångra dessa ändringar.</strong> @@ -474,7 +474,7 @@ Alla ändringar kommer att gå förlorade. Boot loader location: - Sökväg till uppstartshanterare: + Sökväg till starthanterare: @@ -522,7 +522,7 @@ Alla ändringar kommer att gå förlorade. EFI system partition: - EFI system partition: + EFI-partition: @@ -988,7 +988,7 @@ Alla ändringar kommer att gå förlorade. Failed to open %1 - + Kunde inte öppna %1 @@ -2637,12 +2637,12 @@ Output: Resize <strong>%2MiB</strong> partition <strong>%1</strong> to <strong>%3MiB</strong>. - + Ändra <strong>%2MiB</strong>-partitionen <strong>%1</strong> till <strong>%3MB</strong>. Resizing %2MiB partition %1 to %3MiB. - + Ändrar storlek på partitionen %1 från %2MB till %3MB. @@ -2682,7 +2682,7 @@ Output: This computer does not satisfy the minimum requirements for setting up %1.<br/>Setup cannot continue. <a href="#details">Details...</a> - + Datorn uppfyller inte minimikraven för inställning av %1.<br/>Inga inställningar kan inte göras. <a href="#details">Detaljer...</a> @@ -2692,7 +2692,7 @@ Output: This computer does not satisfy some of the recommended requirements for setting up %1.<br/>Setup can continue, but some features might be disabled. - + Några av kraven för inställning av %1 uppfylls inte av datorn.<br/>Inställningarna kan ändå göras men vissa funktioner kommer kanske inte att kunna användas. @@ -2785,7 +2785,7 @@ Output: Failed to write keyboard configuration to existing /etc/default directory. - + Misslyckades med att skriva tangentbordskonfiguration till den existerande mappen /etc/default. @@ -2901,7 +2901,7 @@ Output: passwd terminated with error code %1. - + passwd stoppades med felkod %1. @@ -3052,7 +3052,7 @@ Output: Placeholder - + Platshållare @@ -3098,12 +3098,12 @@ Output: <small>If more than one person will use this computer, you can create multiple accounts after setup.</small> - + <small>Om mer än en person skall använda datorn så kan du skapa flera användarkonton när inställningarna är klara.</small> <small>If more than one person will use this computer, you can create multiple accounts after installation.</small> - + <small>Om mer än en person skall använda datorn så kan du skapa flera användarkonton när installationen är klar.</small> @@ -3134,7 +3134,7 @@ Output: Your passwords do not match! - Dina lösenord matchar inte! + Lösenorden överensstämmer inte! @@ -3150,7 +3150,7 @@ Output: Key - + Nyckel @@ -3237,22 +3237,22 @@ Output: Open help and support website - + Besök webbplatsen för hjälp och support Open issues and bug-tracking website - + Besök webbplatsen för problem och felsökning Open release notes website - + Besök webbplatsen för versionsinformation &Release notes - Versionsinfomation + Versionsinformation, &R @@ -3262,22 +3262,22 @@ Output: &Support - %Support + &Support &About - Om + Om, &A <h1>Welcome to the %1 installer.</h1> - <h1>V&auml;lkommen till %1-installeraren.</h1> + <h1>Välkommen till %1-installeraren.</h1> <h1>Welcome to the Calamares installer for %1.</h1> - + <h1>Välkommen till installationsprogrammet Calamares för %1.</h1> @@ -3292,7 +3292,7 @@ Output: About %1 setup - + Om inställningarna för %1 diff --git a/lang/calamares_tr_TR.ts b/lang/calamares_tr_TR.ts index 371824a34..b957d2b3d 100644 --- a/lang/calamares_tr_TR.ts +++ b/lang/calamares_tr_TR.ts @@ -3257,7 +3257,7 @@ Kuruluma devam edebilirsiniz fakat bazı özellikler devre dışı kalabilir. Open release notes website - + Sürüm Notları web sitesini aç From 5a98a1385680debe7cfd79e15d93ae3e2ed9f31e Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 1 Nov 2019 17:24:10 +0100 Subject: [PATCH 20/22] i18n: [dummypythonqt] Automatic merge of Transifex translations --- .../lang/pt_BR/LC_MESSAGES/dummypythonqt.mo | Bin 966 -> 952 bytes .../lang/pt_BR/LC_MESSAGES/dummypythonqt.po | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.mo b/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.mo index 6e11623883432dbc02374151170aee6b3780718b..dad5673f1796be1ee9ff8989301bbca4df59f8c1 100644 GIT binary patch delta 69 zcmX@czJq;2h-p6~149B33otM+d|+Z=Fa^?#%nS^CK-wHgO9N>)D4hhPErI;Hjh&&4 Ko8K_rVgvwTP71&P delta 83 zcmdnNevExWi0NEL28IM67GPjt_{YS+U<#!9nHd=PfV3-+mIl%xP`Us}TLSq#8#_Z8 Yd3_U$4lhs4Q3%e=DNEdZm+>|u04ov@mjD0& diff --git a/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po b/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po index 4377e6c3e..bee7745dc 100644 --- a/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po +++ b/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po @@ -5,7 +5,7 @@ # # Translators: # Rodrigo de Almeida Sottomaior Macedo , 2017 -# Guilherme Marçal Silva , 2018 +# Guilherme , 2018 # #, fuzzy msgid "" @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-09-15 21:54+0200\n" "PO-Revision-Date: 2016-12-16 12:18+0000\n" -"Last-Translator: Guilherme Marçal Silva , 2018\n" +"Last-Translator: Guilherme , 2018\n" "Language-Team: Portuguese (Brazil) (https://www.transifex.com/calamares/teams/20061/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" From a395ed1113ccd22826e77d6b8bb8ac469e4f265c Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 1 Nov 2019 17:24:10 +0100 Subject: [PATCH 21/22] i18n: [python] Automatic merge of Transifex translations --- lang/python/ja/LC_MESSAGES/python.mo | Bin 8919 -> 9081 bytes lang/python/ja/LC_MESSAGES/python.po | 26 ++++++++++++------------ lang/python/pt_BR/LC_MESSAGES/python.mo | Bin 8356 -> 8342 bytes lang/python/pt_BR/LC_MESSAGES/python.po | 4 ++-- lang/python/sv/LC_MESSAGES/python.mo | Bin 380 -> 897 bytes lang/python/sv/LC_MESSAGES/python.po | 20 ++++++++++-------- 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/lang/python/ja/LC_MESSAGES/python.mo b/lang/python/ja/LC_MESSAGES/python.mo index 462a4d73cbe219ab898db8e8702f0edd2506660c..4722644d851662f7f24454b73118fe8f302957c3 100644 GIT binary patch delta 827 zcmaLUPe>F|9Ki8kwugcU%3$58*)rXVAWb&~B?*lFKm;8Oin@%uNK06u8`P!s&4~XX zke!2Q9T(eJG-D4XY>{6b)R zs!c?m2Su9j6E@=RI+3Fo#R%TO6R7YszQ8@Wiu-T_J**9hG~*PSeQ&WH*U-c@S|Z1> z15KT{B`K+AFwVpo%wY?D!&bESi z7{wx*yx%v!BjHpz@%3=|WC}Y>AezMMNQhiMD8eJ}cwN9XjAPp&5eH|m3xDAw?BrAr za1l>p>tT@wjNwfj#Tb@$GB5!b8}bu@?%KUtO=&f&)v#7Yt)}&m>%R}$smf_d+({${ zoc_K+?WR| z>GIfQWpRHY9LYbdi*B=2Zu!Y;tsbuw3)=OydiLjh{;N>tn48vaMtgbfE^2RVv)PJ! zkW2n&t0kYc+G~PtdTDg_%jC$GqW;FNkY8i>nDz0AuhW^W>yCY`$_?iW_Kv`jAy@ha RlTI%e@UL#o-ze4p_zhPWEY|=4 delta 604 zcmY+=y-QnB7{~EP6UCw+qRp!}NiVg9E}9etrC9lsT8E&ql+%*b9kO}ew^q0?fcQY=XPbEiO7yu zB#dYH7_ZTXwJaVCV+gzO6%Jt&=CK8fXyPHZW85#&hG~3`7OHc{_yW)HDgN_IR-Ukl z1Vmn90;4#OG2F&Z{D~^4DM&bWV*(d&5RY&O8(T#taU50NckIDx?e2aYRqi;d2drt? zyT&O6HJO9ms57n#9!8GHKB^yzvh?Esj$r{u@CM`fE+X;~H}C^$OxJ~9kWZCwIE)UC zV&ai5(!pj+uPnP0&8}YuCF|U)y+%n*r!uo6>4`bp$p79hIpuX#wat=kp4i5&ZSFp3 zq^Hz{(f6sD`(tc0@j&;-Ew@htN)jls@7K*BNr6q48lc73yO|GEA-s+y3+*j3H(*OJi5xAE+ diff --git a/lang/python/ja/LC_MESSAGES/python.po b/lang/python/ja/LC_MESSAGES/python.po index e6906d289..3debe2325 100644 --- a/lang/python/ja/LC_MESSAGES/python.po +++ b/lang/python/ja/LC_MESSAGES/python.po @@ -92,11 +92,11 @@ msgstr "" #: src/modules/umount/main.py:40 msgid "Unmount file systems." -msgstr "ファイルシステムをアンマウントする。" +msgstr "ファイルシステムをアンマウント。" #: src/modules/unpackfs/main.py:41 msgid "Filling up filesystems." -msgstr "ファイルシステムを埋める。" +msgstr "ファイルシステムに書き込んでいます。" #: src/modules/unpackfs/main.py:160 msgid "rsync failed with error code {}." @@ -201,7 +201,7 @@ msgstr "ディスプレイマネージャの設定が不完全です" #: src/modules/initcpiocfg/main.py:36 msgid "Configuring mkinitcpio." -msgstr "mkinitcpioを設定中" +msgstr "mkinitcpioを設定しています。" #: src/modules/initcpiocfg/main.py:192 #: src/modules/luksopenswaphookcfg/main.py:100 @@ -213,7 +213,7 @@ msgstr "
{!s}
を使用するのにルートマウントポイント #: src/modules/luksopenswaphookcfg/main.py:35 msgid "Configuring encrypted swap." -msgstr "暗号化したswapを設定中" +msgstr "暗号化したswapを設定しています。" #: src/modules/rawfs/main.py:35 msgid "Installing data." @@ -274,7 +274,7 @@ msgstr "machine-id の生成" #: src/modules/packages/main.py:62 #, python-format msgid "Processing packages (%(count)d / %(total)d)" -msgstr "パッケージの処理中 (%(count)d / %(total)d)" +msgstr "パッケージを処理しています (%(count)d / %(total)d)" #: src/modules/packages/main.py:64 src/modules/packages/main.py:74 msgid "Install packages." @@ -284,13 +284,13 @@ msgstr "パッケージのインストール" #, python-format msgid "Installing one package." msgid_plural "Installing %(num)d packages." -msgstr[0] " %(num)d パッケージのインストール中。" +msgstr[0] " %(num)d パッケージをインストールしています。" #: src/modules/packages/main.py:70 #, python-format msgid "Removing one package." msgid_plural "Removing %(num)d packages." -msgstr[0] " %(num)d パッケージの削除中。" +msgstr[0] " %(num)d パッケージを削除しています。" #: src/modules/bootloader/main.py:51 msgid "Install bootloader." @@ -306,7 +306,7 @@ msgstr "ハードウェアクロックの設定" #: src/modules/dracut/main.py:36 msgid "Creating initramfs with dracut." -msgstr "dracutとinitramfsを作成中" +msgstr "dracutとinitramfsを作成しています。" #: src/modules/dracut/main.py:58 msgid "Failed to run dracut on the target" @@ -318,15 +318,15 @@ msgstr "停止コードは {} でした" #: src/modules/initramfscfg/main.py:41 msgid "Configuring initramfs." -msgstr "initramfsを設定中" +msgstr "initramfsを設定しています。" #: src/modules/openrcdmcryptcfg/main.py:34 msgid "Configuring OpenRC dmcrypt service." -msgstr "OpenRC dmcryptサービスを設定中" +msgstr "OpenRC dmcryptサービスを設定しています。" #: src/modules/fstab/main.py:38 msgid "Writing fstab." -msgstr "fstabを書き込み中" +msgstr "fstabを書き込んでいます。" #: src/modules/dummypython/main.py:44 msgid "Dummy python job." @@ -338,8 +338,8 @@ msgstr "Dummy python step {}" #: src/modules/localecfg/main.py:39 msgid "Configuring locales." -msgstr "ローカルを設定中" +msgstr "ロケールを設定しています。" #: src/modules/networkcfg/main.py:37 msgid "Saving network configuration." -msgstr "ネットワーク設定を保存中" +msgstr "ネットワーク設定を保存しています。" diff --git a/lang/python/pt_BR/LC_MESSAGES/python.mo b/lang/python/pt_BR/LC_MESSAGES/python.mo index 9341ca4815f112cddd44fb72246b9da4ac27c691..a004f563d372fcb11c7dbb55f77a7853798d7bc7 100644 GIT binary patch delta 587 zcmXZZIY5_(eRE^x5YnB7J_5q=-1RBI{UP zClbYN?8Zx6#U~8wdcBB=FH5H5l&$ar?D&`GKUKRvHyb;f<}U8 ztica#$8T)Gau$Oa#$GhB4fl{o&UjHd&2GUB)cgRo6L+X}eo*)I*!*6Cfrb5e z@A-zh(bwu85XBJl9qhz34&Vdo2fyPi{^Ax+^83_~D~zFo78X&ja)tIraQvFVK7&_G i;XHlT0vXf}SW+0)WsW%kiusQLp}aY0=G delta 601 zcmXZZPbh3`7{o*5k#k;qC5X1<60Xy6Fmqx#@?oWT};dmZPHT5^RGXki}fsID?kd&h9W;rqwK5U5ui&6^(j0QR779C$W}zHjE|&KT71Q(C`UhEBNVWg~ diff --git a/lang/python/pt_BR/LC_MESSAGES/python.po b/lang/python/pt_BR/LC_MESSAGES/python.po index a5da0a8fc..493d4deed 100644 --- a/lang/python/pt_BR/LC_MESSAGES/python.po +++ b/lang/python/pt_BR/LC_MESSAGES/python.po @@ -5,7 +5,7 @@ # # Translators: # André Marcelo Alvarenga , 2019 -# Guilherme Marçal Silva , 2019 +# Guilherme , 2019 # #, fuzzy msgid "" @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-09-15 21:54+0200\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: Guilherme Marçal Silva , 2019\n" +"Last-Translator: Guilherme , 2019\n" "Language-Team: Portuguese (Brazil) (https://www.transifex.com/calamares/teams/20061/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/lang/python/sv/LC_MESSAGES/python.mo b/lang/python/sv/LC_MESSAGES/python.mo index 6af85532a909fc040a9f1b105f44590e45013094..f31e39ee55ba61274c3b36b2681fbbb917814863 100644 GIT binary patch literal 897 zcmZuvL2uJA7!5E$3KC*mkPruRKx$Q-q-7disvfq{p#r5<6E=yPm$+?6YFDzMxp*TA(amUS0=0xofHN+(kIWUznueE(^O z9CwC6xBt=}@|jeI_VhT3>A`%gX()YS5BhY-^Q7?5C(Ll4G`#v_>NTmiN9vycXs6~O z>=#TM8Y(7q#*9=xdBz0oXL3Y>oC~d`cvv|1kSNA;TpA5IoBAYJ@Ho*EQkfVt)4uC2 z77ND|`y?ZN=0tMpMl54f98S9i7VS1XZ@2F1+^yQZZm+XGQr+?FLn#awDCO-8wHkhA z+*!sF(IOEpNpsVF6&}&%Iuz7bZ!r_xndbTl4`1bB4*`O zw;L^TF>F@^x!)%BYRg`}1g;nwn{u;iITW?|I7$T_{9od_*X14|yr<|7`6GR${goS- f^AB0Z6`7oWRB_JKJS|=Y6OI+6D#@|(`(6A3(o_Bp delta 69 zcmZo<|HEW)Pl#nI0}wC*u?!Ha05LNV>i{tbSOBpTP|^}egVeyl, YEAR. # +# Translators: +# Jan-Olof Svensson, 2019 +# #, fuzzy msgid "" msgstr "" @@ -10,6 +13,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-09-15 21:54+0200\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" +"Last-Translator: Jan-Olof Svensson, 2019\n" "Language-Team: Swedish (https://www.transifex.com/calamares/teams/20061/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -208,7 +212,7 @@ msgstr "" #: src/modules/rawfs/main.py:35 msgid "Installing data." -msgstr "" +msgstr "Installerar data." #: src/modules/services-openrc/main.py:38 msgid "Configure OpenRC services" @@ -268,21 +272,21 @@ msgstr "" #: src/modules/packages/main.py:64 src/modules/packages/main.py:74 msgid "Install packages." -msgstr "" +msgstr "Installera paket." #: src/modules/packages/main.py:67 #, python-format msgid "Installing one package." msgid_plural "Installing %(num)d packages." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Installerar ett paket." +msgstr[1] "Installerar %(num)d paket." #: src/modules/packages/main.py:70 #, python-format msgid "Removing one package." msgid_plural "Removing %(num)d packages." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Tar bort ett paket." +msgstr[1] "Tar bort %(num)d paket." #: src/modules/bootloader/main.py:51 msgid "Install bootloader." @@ -294,7 +298,7 @@ msgstr "" #: src/modules/hwclock/main.py:35 msgid "Setting hardware clock." -msgstr "" +msgstr "Ställer hårdvaruklockan." #: src/modules/dracut/main.py:36 msgid "Creating initramfs with dracut." @@ -318,7 +322,7 @@ msgstr "" #: src/modules/fstab/main.py:38 msgid "Writing fstab." -msgstr "" +msgstr "Skriver fstab." #: src/modules/dummypython/main.py:44 msgid "Dummy python job." From ffbc1a3e7d04e68ece3e87002f9ad29e5402c3ab Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 1 Nov 2019 17:38:19 +0100 Subject: [PATCH 22/22] Changes: post-release housekeeping --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c970a5d7..2d1cb83f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,10 +40,10 @@ cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.16 + VERSION 3.2.17 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development ### OPTIONS #