File indexing completed on 2024-04-28 03:59:09

0001 // vi: ts=8 sts=4 sw=4
0002 /*
0003     This file is part of the KDE libraries
0004     SPDX-FileCopyrightText: 1998 Pietro Iglio <iglio@fub.it>
0005     SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
0006     SPDX-FileCopyrightText: 2004, 2005 Andrew Coles <andrew_coles@yahoo.co.uk>
0007     SPDX-FileCopyrightText: 2006, 2007 Olivier Goffart <ogoffart @ kde.org>
0008     SPDX-FileCopyrightText: 2015 Elvis Angelaccio <elvis.angelaccio@kde.org>
0009 
0010     SPDX-License-Identifier: LGPL-2.0-only
0011 */
0012 #ifndef KNEWPASSWORDWIDGET_H
0013 #define KNEWPASSWORDWIDGET_H
0014 
0015 #include <KPassword>
0016 #include <KPasswordLineEdit>
0017 #include <QWidget>
0018 #include <memory>
0019 
0020 #include <kwidgetsaddons_export.h>
0021 
0022 /**
0023  * @class KNewPasswordWidget knewpasswordwidget.h KNewPasswordWidget
0024  *
0025  * @short A password input widget.
0026  *
0027  * This widget allows the user to enter a new password.
0028  *
0029  * The password has to be entered twice to check if the passwords
0030  * match. A hint about the strength of the entered password is also
0031  * shown.
0032  *
0033  * In order to embed this widget in your custom password dialog,
0034  * you may want to connect to the passwordStatus() signal.
0035  * This way you can e.g. disable the OK button if the passwords
0036  * don't match, warn the user if the password is too weak, and so on.
0037  *
0038  * \section usage Usage Example
0039  * \subsection Setup
0040  *
0041  * \code
0042  *  KNewPasswordWidget *m_passwordWidget = new KNewPasswordWidget(this);
0043  *  // set a background warning color (taken from the current color scheme)
0044  *  KColorScheme colorScheme(QPalette::Active, KColorScheme::View);
0045  *  m_passwordWidget->setBackgroundWarningColor(colorScheme.background(KColorScheme::NegativeBackground).color());
0046  *  // listen to password status updates
0047  *  connect(m_passwordWidget, &KNewPasswordWidget::passwordStatusChanged, this, &MyCustomDialog::slotPasswordStatusChanged);
0048  *  ...
0049  * \endcode
0050  *
0051  * \subsection update Update your custom dialog
0052  *
0053  * @snippet knewpasswordwidget_test.cpp update_custom_dialog
0054  *
0055  * \subsection accept Accept your custom dialog
0056  *
0057  * @snippet knewpasswordwidget_test.cpp accept_custom_dialog
0058  *
0059  * @author Geert Jansen <jansen@kde.org>
0060  * @author Olivier Goffart <ogoffart@kde.org>
0061  * @author Elvis Angelaccio <elvis.angelaccio@kde.org>
0062  * @since 5.16
0063  */
0064 class KWIDGETSADDONS_EXPORT KNewPasswordWidget : public QWidget
0065 {
0066     Q_OBJECT
0067     Q_PROPERTY(PasswordStatus passwordStatus READ passwordStatus)
0068     Q_PROPERTY(bool allowEmptyPasswords READ allowEmptyPasswords WRITE setAllowEmptyPasswords)
0069     Q_PROPERTY(int minimumPasswordLength READ minimumPasswordLength WRITE setMinimumPasswordLength)
0070     Q_PROPERTY(int maximumPasswordLength READ maximumPasswordLength WRITE setMaximumPasswordLength)
0071     Q_PROPERTY(int reasonablePasswordLength READ reasonablePasswordLength WRITE setReasonablePasswordLength)
0072     Q_PROPERTY(int passwordStrengthWarningLevel READ passwordStrengthWarningLevel WRITE setPasswordStrengthWarningLevel)
0073     Q_PROPERTY(QColor backgroundWarningColor READ backgroundWarningColor WRITE setBackgroundWarningColor)
0074     Q_PROPERTY(bool passwordStrengthMeterVisible READ isPasswordStrengthMeterVisible WRITE setPasswordStrengthMeterVisible)
0075     /**
0076      * @since 5.31
0077      */
0078 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(6, 0)
0079     Q_PROPERTY(bool revealPasswordAvailable READ isRevealPasswordAvailable WRITE setRevealPasswordAvailable)
0080 #endif
0081     Q_PROPERTY(KPassword::RevealMode revealPasswordMode READ revealPasswordMode WRITE setRevealPasswordMode)
0082 
0083 public:
0084     /**
0085      * Status of the password being typed in the widget.
0086      */
0087     enum PasswordStatus {
0088         EmptyPasswordNotAllowed, /**< Both passwords fields empty, but minimum length > 0. */
0089         PasswordTooShort, /**< Password length is too low. */
0090         PasswordNotVerified, /**< Password and verification password don't match. */
0091         WeakPassword, /**< Passwords match but the strength level is not enough. */
0092         StrongPassword, /**< Passwords match and the strength level is good. */
0093     };
0094     Q_ENUM(PasswordStatus)
0095 
0096     /**
0097      * This enum describe when the reveal password button is visible.
0098      * @since 6.0
0099      */
0100     enum class RevealPasswordMode {
0101         /**
0102          * Display the button when entering a new password, but doesn't let you see a
0103          * previously entered password. This is the default.
0104          */
0105         OnlyNew,
0106         /**
0107          * Never display the reveal button.
0108          */
0109         Never,
0110         /**
0111          * Always display the reveal button. Usefull in a password manager for example.
0112          */
0113         Always,
0114     };
0115     Q_ENUM(RevealPasswordMode)
0116 
0117     /**
0118      * Constructs a password widget.
0119      *
0120      * @param parent Passed to lower level constructor.
0121      */
0122     explicit KNewPasswordWidget(QWidget *parent = nullptr);
0123 
0124     /**
0125      * Destructs the password widget.
0126      */
0127     ~KNewPasswordWidget() override;
0128 
0129     /**
0130      * The current status of the password in the widget.
0131      */
0132     PasswordStatus passwordStatus() const;
0133 
0134     /**
0135      * Allow empty passwords?
0136      *
0137      * @return true if minimumPasswordLength() == 0
0138      */
0139     bool allowEmptyPasswords() const;
0140 
0141     /**
0142      * Minimum acceptable password length.
0143      */
0144     int minimumPasswordLength() const;
0145 
0146     /**
0147      * Maximum acceptable password length.
0148      */
0149     int maximumPasswordLength() const;
0150 
0151     /**
0152      * Password length that is expected to be reasonably safe.
0153      */
0154     int reasonablePasswordLength() const;
0155 
0156     /**
0157      * Password strength level below which a warning is given
0158      */
0159     int passwordStrengthWarningLevel() const;
0160 
0161     /**
0162      * The color used as warning for the verification password field's background.
0163      */
0164     QColor backgroundWarningColor() const;
0165 
0166     /**
0167      * Whether the password strength meter is visible.
0168      */
0169     bool isPasswordStrengthMeterVisible() const;
0170 
0171 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(6, 0)
0172     /**
0173      * Whether the visibility trailing action in the line edit is visible.
0174      * @since 5.31
0175      */
0176     [[deprecated("Use revealPasswordMode instead.")]] bool isRevealPasswordAvailable() const;
0177 #endif
0178 
0179     /**
0180      * Whether the visibility trailing action in the line edit is visible.
0181      * @since 6.0
0182      */
0183     KPassword::RevealMode revealPasswordMode() const;
0184 
0185     /**
0186      * Returns the password entered.
0187      * @note Only returns meaningful data when passwordStatus
0188      *       is either WeakPassword or StrongPassword.
0189      */
0190     QString password() const;
0191 
0192 public Q_SLOTS:
0193 
0194     /**
0195      * Allow empty passwords? - Default: true
0196      *
0197      * same as setMinimumPasswordLength( allowed ? 0 : 1 )
0198      */
0199     void setAllowEmptyPasswords(bool allowed);
0200 
0201     /**
0202      * Minimum acceptable password length.
0203      *
0204      * Default: 0
0205      *
0206      * @param minLength The new minimum password length
0207      */
0208     void setMinimumPasswordLength(int minLength);
0209 
0210     /**
0211      * Maximum acceptable password length.
0212      *
0213      * @param maxLength The new maximum password length.
0214      */
0215     void setMaximumPasswordLength(int maxLength);
0216 
0217     /**
0218      * Password length that is expected to be reasonably safe.
0219      * The value is guaranteed to be in the range from 1 to maximumPasswordLength().
0220      *
0221      * Used to compute the strength level
0222      *
0223      * Default: 8 - the standard UNIX password length
0224      *
0225      * @param reasonableLength The new reasonable password length.
0226      */
0227     void setReasonablePasswordLength(int reasonableLength);
0228 
0229     /**
0230      * Set the password strength level below which a warning is given
0231      * The value is guaranteed to be in the range from 0 to 99. Empty passwords score 0;
0232      * non-empty passwords score up to 100, depending on their length and whether they
0233      * contain numbers, mixed case letters and punctuation.
0234      *
0235      * Default: 1 - warn if the password has no discernible strength whatsoever
0236      * @param warningLevel The level below which a warning should be given.
0237      */
0238     void setPasswordStrengthWarningLevel(int warningLevel);
0239 
0240     /**
0241      * When the verification password does not match, the background color
0242      * of the verification field is set to @p color. As soon as the passwords match,
0243      * the original color of the verification field is restored.
0244      */
0245     void setBackgroundWarningColor(const QColor &color);
0246 
0247     /**
0248      * Whether to show the password strength meter (label and progress bar).
0249      * Default is true.
0250      */
0251     void setPasswordStrengthMeterVisible(bool visible);
0252 
0253 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(6, 0)
0254     /**
0255      * Whether to show the visibility trailing action in the line edit.
0256      * Default is true. This can be used to honor the lineedit_reveal_password
0257      * kiosk key, for example:
0258      * \code
0259      * passwordWidget.setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
0260      * \endcode
0261      * @since 5.31
0262      */
0263     [[deprecated("Use setRevealPasswordMode instead.")]] void setRevealPasswordAvailable(bool reveal);
0264 #endif
0265 
0266     /**
0267      * Set when the reveal password button will be visible.
0268      *
0269      * The default is RevealPasswordMode::OnlyNew and the reveal password button will
0270      * only be visible when entering a new password.
0271      *
0272      * This can be used to honor the lineedit_reveal_password kiosk key, for example:
0273      *
0274      * @code{.cpp}
0275      * if (KAuthorized::authorize(QStringLiteral("lineedit_reveal_password"))) {
0276      *     newPasswordWidget.setRevealPasswordMode(KPassword::RevealMode::OnlyNew);
0277      * } else {
0278      *     newPasswordWidget.setRevealPasswordMode(KPassword::RevealMode::Never);
0279      * }
0280      * @endcode
0281      * @since 6.0
0282      */
0283     void setRevealPasswordMode(KPassword::RevealMode revealPasswordMode);
0284 
0285 Q_SIGNALS:
0286 
0287     /**
0288      * Notify about the current status of the password being typed.
0289      */
0290     void passwordStatusChanged();
0291 
0292 private:
0293     std::unique_ptr<class KNewPasswordWidgetPrivate> const d;
0294 
0295     Q_DISABLE_COPY(KNewPasswordWidget)
0296 };
0297 
0298 #endif // KNEWPASSWORDWIDGET_H