1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
4     SPDX-FileCopyrightText: 2000 Dawit Alemayehu <adawit@kde.org>
5     SPDX-FileCopyrightText: 2007 Olivier Goffart <ogoffart at kde.org>
6     SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org>
7 
8     SPDX-License-Identifier: LGPL-2.0-or-later
9 */
10 
11 #ifndef KPASSWORDDIALOG_H
12 #define KPASSWORDDIALOG_H
13 
14 #include <QDialog>
15 #include <QDialogButtonBox>
16 #include <memory>
17 
18 #include <kwidgetsaddons_export.h>
19 
20 /**
21  * @class KPasswordDialog kpassworddialog.h KPasswordDialog
22  *
23  * A dialog for requesting a password and optionally a login from the end user.
24  *
25  * \section usage Usage Example
26  *
27  * Requesting a simple password, asynchronous
28  *
29  * \code
30  *  KPasswordDialog *dlg = new KPasswordDialog(parent);
31  *  dlg->setPrompt(i18n("Enter a password"));
32  *  connect(dlg, &KPasswordDialog::gotPassword,
33  *          this, [this](const QString &password) { setPassword(password); });
34  *  connect(dlg, &QDialog::rejected, this, [this]() { slotCancel(); });
35  *  dlg->show();
36  * \endcode
37  *
38  * Requesting a login and a password, synchronous
39  *
40  * \code
41  *  KPasswordDialog dlg(parent, KPasswordDialog::ShowUsernameLine);
42  *  dlg.setPrompt(i18n("Enter a login and a password"));
43  *  if(!dlg.exec()) {
44  *      return; //the user canceled
45  *  }
46  *  use(dlg.username(), dlg.password());
47  * \endcode
48  *
49  * \image html kpassworddialog.png "KPasswordDialog"
50  *
51  * @short dialog for requesting login and password from the end user
52  */
53 class KWIDGETSADDONS_EXPORT KPasswordDialog : public QDialog
54 {
55     Q_OBJECT
56 
57 public:
58     /**
59      * @see KPasswordDialogFlags
60      */
61     enum KPasswordDialogFlag {
62         NoFlags = 0x00,
63         /**
64          * If this flag is set, the "keep this password" checkbox will been shown,
65          * otherwise, it will not be shown and keepPassword will have no effect
66          */
67         ShowKeepPassword = 0x01,
68         /**
69          * If this flag is set, there will be an additional line to let the user enter his login.
70          * otherwise, only the password line will be shown.
71          */
72         ShowUsernameLine = 0x02,
73         /**
74          * If this flag is set, the login lineedit will be in read only mode.
75          */
76         UsernameReadOnly = 0x04,
77         /**
78          * If this flag is set, the Anonymous Login checkbox will be displayed
79          * @since 4.1
80          */
81         ShowAnonymousLoginCheckBox = 0x08,
82         /**
83          * If this flag is set, there will be an additional line to let the user enter the domain.
84          * @since 4.1
85          */
86         ShowDomainLine = 0x10,
87         /**
88          * If this flag is set, the domain lineedit will be in read only mode.
89          * @since 4.1
90          */
91         DomainReadOnly = 0x20,
92     };
93     /**
94      * Stores a combination of #KPasswordDialogFlag values.
95      */
96     Q_DECLARE_FLAGS(KPasswordDialogFlags, KPasswordDialogFlag)
97 
98     enum ErrorType {
99         UnknownError = 0,
100 
101         /**
102          * A problem with the user name as entered
103          */
104         UsernameError,
105 
106         /**
107          * Incorrect password
108          */
109         PasswordError,
110 
111         /**
112          * Error preventing further attempts, will result in disabling most of the interface
113          */
114         FatalError,
115 
116         /**
117          * A problem with the domain as entered
118          * @since 4.1
119          */
120         DomainError,
121     };
122 
123     /**
124      * create a password dialog
125      *
126      * @param parent the parent widget
127      * @param flags a set of KPasswordDialogFlag flags
128      */
129     explicit KPasswordDialog(QWidget *parent = nullptr, const KPasswordDialogFlags &flags = KPasswordDialog::NoFlags);
130 
131     /**
132      * Destructor
133      */
134     ~KPasswordDialog() override;
135 
136     /**
137      * Sets the prompt to show to the user.
138      * @param prompt        instructional text to be shown.
139      */
140     void setPrompt(const QString &prompt);
141 
142     /**
143      * Returns the prompt
144      */
145     QString prompt() const;
146 
147     /**
148      * Set the icon that appears next to the prompt.
149      * @since 5.63
150      */
151     void setIcon(const QIcon &icon);
152 
153     /**
154      * Returns the icon that appears next to the prompt.
155      */
156     QIcon icon() const;
157 
158 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(5, 63)
159     /**
160      * set an image that appears next to the prompt.
161      * @deprecated since 5.63 use setIcon()
162      */
163     KWIDGETSADDONS_DEPRECATED_VERSION(5, 63, "Use KPasswordDialog::setIcon(const QIcon &)")
164     void setPixmap(const QPixmap &);
165     /**
166      * @deprecated since 5.63 use icon()
167      */
168     KWIDGETSADDONS_DEPRECATED_VERSION(5, 63, "Use KPasswordDialog::icon()")
169     QPixmap pixmap() const;
170 #endif
171 
172     /**
173      * Adds a comment line to the dialog.
174      *
175      * This function allows you to add one additional comment
176      * line to this widget.  Calling this function after a
177      * comment has already been added will not have any effect.
178      *
179      * @param label       label for comment (ex:"Command:")
180      * @param comment     the actual comment text.
181      */
182     void addCommentLine(const QString &label, const QString &comment);
183 
184     /**
185      * Shows an error message in the dialog box. Prevents having to show a dialog-on-a-dialog.
186      *
187      * @param message the error message to show
188      */
189     void showErrorMessage(const QString &message, const ErrorType type = PasswordError);
190 
191     /**
192      * Returns the password entered by the user.
193      * @return the password
194      */
195     QString password() const;
196 
197     /**
198      * set the default username.
199      */
200     void setUsername(const QString &);
201 
202     /**
203      * Returns the username entered by the user.
204      * @return the user name
205      */
206     QString username() const;
207 
208     /**
209      * set the default domain.
210      * @since 4.1
211      */
212     void setDomain(const QString &);
213 
214     /**
215      * Returns the domain entered by the user.
216      * @return the domain name
217      * @since 4.1
218      */
219     QString domain() const;
220 
221     /**
222      * set anonymous mode (all other fields will be grayed out)
223      * @since 4.1
224      */
225     void setAnonymousMode(bool anonymous);
226 
227     /**
228      * @return anonymous mode has been selected.
229      * @since 4.1
230      */
231     bool anonymousMode() const;
232 
233     /**
234      * Determines whether supplied authorization should
235      * persist even after the application has been closed.
236      *
237      * this is set with the check password checkbox is the ShowKeepCheckBox flag
238      * is set in the constructor, if it is not set, this function return false
239      *
240      * @return true to keep the password
241      */
242     bool keepPassword() const;
243 
244     /**
245      * Check or uncheck the "keep password" checkbox.
246      * This can be used to check it before showing the dialog, to tell
247      * the user that the password is stored already (e.g. in the wallet).
248      * enableKeep must have been set to true in the constructor.
249      *
250      * has only effect if ShowKeepCheckBox is set in the constructor
251      */
252     void setKeepPassword(bool b);
253 
254     /**
255      * Sets the username field read-only and sets the
256      * focus to the password field.
257      *
258      * this can also be set by passing UsernameReadOnly as flag in the constructor
259      *
260      * @param readOnly true to set the user field to read-only
261      */
262     void setUsernameReadOnly(bool readOnly);
263 
264     /**
265      * Presets the password.
266      * If the password is not empty, the ability to show the password will not be available.
267      * @param password the password to set
268      */
269     void setPassword(const QString &password);
270 
271     /**
272      * Presets a number of login+password pairs that the user can choose from.
273      * The passwords can be empty if you simply want to offer usernames to choose from.
274      *
275      * This require the flag ShowUsernameLine to be set in the constructoe, and not the flag UsernameReadOnly
276      * @param knownLogins map of known logins: the keys are usernames, the values are passwords.
277      */
278     void setKnownLogins(const QMap<QString, QString> &knownLogins);
279 
280     /**
281      * @internal
282      */
283     void accept() override;
284 
285     /**
286      * Returns the button box used in the dialog.
287      * This can be used to add new buttons.
288      *
289      * @return the button box
290      *
291      * @since 5.0
292      */
293     QDialogButtonBox *buttonBox() const;
294 
295     /**
296      * Sets contextual help for the username input field. This displays a
297      * somewhat visual hint in the UI giving very visible access to a whats-this
298      * style input description for the user name line. This is particularly useful
299      * when the user name may require or support special input syntax.
300      * For example windows-like auth dialogs supports multiple different logon
301      * name syntax.
302      * @since 5.76
303      */
304     void setUsernameContextHelp(const QString &help);
305 
306     /**
307      * Whether to show the visibility trailing action in the line edit.
308      * Default is @c true. This can be used to honor the lineedit_reveal_password
309      * kiosk key, for example:
310      * \code
311      * dlg->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
312      * \endcode
313      * @since 5.84
314      */
315     void setRevealPasswordAvailable(bool reveal);
316 
317     /**
318      * Whether the visibility trailing action in the line edit is visible.
319      * @since 5.84
320      */
321     bool isRevealPasswordAvailable() const;
322 
323 Q_SIGNALS:
324     /**
325      * emitted when the dialog has been accepted
326      * @param password  the entered password
327      * @param keep true if the "remember password" checkbox was checked, false otherwise.  false if ShowKeepPassword was not set in the constructor
328      */
329     void gotPassword(const QString &password, bool keep);
330 
331     /**
332      * emitted when the dialog has been accepted, and ShowUsernameLine was set on the constructor
333      * @param username the entered username
334      * @param password  the entered password
335      * @param keep true if the "remember password" checkbox was checked, false otherwise.  false if ShowKeepPassword was not set in the constructor
336      */
337     void gotUsernameAndPassword(const QString &username, const QString &password, bool keep);
338 
339 protected:
340     /**
341      * Virtual function that can be overridden to provide password
342      * checking in derived classes. It should return @p true if the
343      * password is valid, @p false otherwise.
344      */
345     virtual bool checkPassword();
346 
347 private:
348     friend class KPasswordDialogPrivate;
349     std::unique_ptr<class KPasswordDialogPrivate> const d;
350 
351     Q_DISABLE_COPY(KPasswordDialog)
352 };
353 
354 Q_DECLARE_OPERATORS_FOR_FLAGS(KPasswordDialog::KPasswordDialogFlags)
355 
356 #endif
357