QtPass Developer documentation
QtPass test coverage
Current view: top level - src/usersdialog.h Coverage Total Hit
Test: QtPass Lines: 100.0 % 2 2
Test Date: 2026-11-14 13:19:18 Functions: - 0 0

            Line data    Source code
       1              : // SPDX-FileCopyrightText: 2015 Anne Jan Brouwer
       2              : // SPDX-License-Identifier: GPL-3.0-or-later
       3              : /**
       4              :  * @file
       5              :  * @brief UsersDialog, the recipient picker for a folder's `.gpg-id`.
       6              :  */
       7              : #ifndef SRC_USERSDIALOG_H_
       8              : #define SRC_USERSDIALOG_H_
       9              : 
      10              : #include "appsettings.h"
      11              : #include "userinfo.h"
      12              : 
      13              : #include <QDialog>
      14              : #include <QList>
      15              : #include <QRegularExpression>
      16              : #include <QScopedPointer>
      17              : 
      18              : namespace Ui {
      19              : class UsersDialog;
      20              : }
      21              : 
      22              : class Pass;
      23              : class QKeyEvent;
      24              : class QListWidgetItem;
      25              : 
      26              : /**
      27              :  * @class UsersDialog
      28              :  * @ingroup keys
      29              :  * @brief Dialog for selecting GPG recipients for password encryption.
      30              :  *
      31              :  * UsersDialog allows users to select which GPG keys to encrypt passwords to.
      32              :  * It displays available keys, supports filtering, and shows key expiration
      33              :  * status.
      34              :  */
      35              : class UsersDialog : public QDialog {
      36          187 :   Q_OBJECT
      37              : 
      38              : public:
      39              :   /** @brief Whether the recipients on disk are ticked when it opens. */
      40              :   enum class Preselect {
      41              :     FromList, ///< The folder's recipient list, as the backend reads it.
      42              :     Nothing,  ///< None: for a store that had no list when it was chosen.
      43              :   };
      44              : 
      45              :   /**
      46              :    * @brief Construct users dialog.
      47              :    * @param pass Active Pass backend.
      48              :    * @param s Application settings snapshot.
      49              :    * @param dir Password store directory path.
      50              :    * @param parent Parent widget.
      51              :    */
      52              :   explicit UsersDialog(Pass *pass, const AppSettings &s, QString dir,
      53              :                        QWidget *parent = nullptr);
      54              :   /**
      55              :    * @brief Construct users dialog, saying what to preselect.
      56              :    * @param pass Active Pass backend.
      57              :    * @param s Application settings snapshot.
      58              :    * @param dir Password store directory path.
      59              :    * @param preselect What is ticked when it opens.
      60              :    * @param parent Parent widget.
      61              :    */
      62              :   UsersDialog(Pass *pass, const AppSettings &s, QString dir,
      63              :               Preselect preselect, QWidget *parent = nullptr);
      64              :   /**
      65              :    * @brief Destroys the dialog and its generated form.
      66              :    */
      67              :   ~UsersDialog() override;
      68              : 
      69              :   /**
      70              :    * @brief Choose whether OK runs Pass::Init on the folder.
      71              :    *
      72              :    * On by default. Off, the dialog only collects the selection; the caller
      73              :    * reads selectedUsers() and initialises the folder itself (new profiles,
      74              :    * which must not go through the backend of the active store).
      75              :    * @param initOnAccept false to skip Pass::Init.
      76              :    */
      77            3 :   void setInitOnAccept(bool initOnAccept) { m_initOnAccept = initOnAccept; }
      78              : 
      79              :   /**
      80              :    * @brief The key list with the user's choice in each entry's enabled flag.
      81              :    * @return All listed users; the selected ones have enabled == true.
      82              :    */
      83              :   [[nodiscard]] auto selectedUsers() const -> QList<UserInfo> {
      84              :     return m_userList;
      85              :   }
      86              : 
      87              :   /**
      88              :    * @brief Whether at least one key is ticked.
      89              :    * @return true if Init would get a recipient.
      90              :    */
      91              :   [[nodiscard]] auto hasSelection() const -> bool;
      92              : 
      93              : public slots:
      94              :   /**
      95              :    * @brief Handle dialog acceptance.
      96              :    */
      97              :   void accept() override;
      98              : 
      99              : protected:
     100              :   /**
     101              :    * @brief Handle key press.
     102              :    * @param event Key event.
     103              :    */
     104              :   void keyPressEvent(QKeyEvent *event) override;
     105              : 
     106              : private slots:
     107              :   /**
     108              :    * @brief Handle user selection change.
     109              :    * @param item Changed list item.
     110              :    */
     111              :   void itemChange(QListWidgetItem *item);
     112              :   /**
     113              :    * @brief Filter user list.
     114              :    * @param filter Filter text.
     115              :    */
     116              :   void on_lineEdit_textChanged(const QString &filter);
     117              :   /**
     118              :    * @brief Handle select all checkbox.
     119              :    */
     120              :   void on_checkBox_clicked();
     121              :   /**
     122              :    * @brief Import a GPG key and refresh the list.
     123              :    */
     124              :   void on_importKeyButton_clicked();
     125              :   /**
     126              :    * @brief Make the key gpg just imported the current row. gpg reports a
     127              :    * 16-character long ID (IMPORTED) or a 40-character fingerprint
     128              :    * (IMPORT_OK), so the two are compared both ways, by suffix.
     129              :    * @param importedKey What gpg reported.
     130              :    */
     131              :   void selectImportedKey(const QString &importedKey);
     132              : 
     133              : private:
     134              :   /// The widgets from usersdialog.ui.
     135              :   QScopedPointer<Ui::UsersDialog> ui;
     136              :   Pass *m_pass;               /**< Active Pass backend */
     137              :   QString m_passStore;        /**< Password store root path */
     138              :   QString m_gpgExe;           /**< GPG executable path */
     139              :   QList<UserInfo> m_userList; /**< List of available GPG users */
     140              :   bool m_initOnAccept{true};  /**< Whether accept() runs Pass::Init. */
     141              :   /// Enable OK only while at least one key is ticked (hasSelection()).
     142              :   void updateOkButton();
     143              :   QString m_dir;                               /**< Password store directory */
     144              :   Preselect m_preselect = Preselect::FromList; /**< What opens ticked */
     145              :   QString m_lastFilter;                  /**< Last filter text for caching */
     146              :   QString m_cachedPatternString;         /**< Cached pattern string */
     147              :   QRegularExpression m_cachedNameFilter; /**< Cached regex filter */
     148              :   mutable QDateTime m_cachedCurrentDateTime; /**< Cached current date/time for
     149              :                                                      expiry checks */
     150              :   mutable bool m_cachedDateTimeValid =
     151              :       false; /**< Whether cached date/time is valid */
     152              : 
     153              :   /// Attach WindowStateStore, which restores the dialog's saved geometry
     154              :   /// now and saves it under "usersDialog" when the dialog closes.
     155              :   void restoreDialogState();
     156              : 
     157              :   /**
     158              :    * @brief Connect dialog signals.
     159              :    */
     160              :   void connectSignals();
     161              : 
     162              :   /**
     163              :    * @brief Load GPG keys and determine secret key status.
     164              :    * @return true if successful, false if keys could not be loaded.
     165              :    */
     166              :   auto loadGpgKeys() -> bool;
     167              : 
     168              :   /**
     169              :    * @brief Mark which keys have secret counterparts.
     170              :    * @param users List of users to mark.
     171              :    */
     172              :   void markSecretKeys(QList<UserInfo> &users);
     173              : 
     174              :   /**
     175              :    * @brief Load recipients and handle missing keys.
     176              :    */
     177              :   void loadRecipients();
     178              :   /**
     179              :    * @brief Show @p text above the key list in bold red, for a recipient list
     180              :    * that could not be verified.
     181              :    * @param text The warning, plain text.
     182              :    */
     183              :   void showRecipientWarning(const QString &text);
     184              :   /**
     185              :    * @brief Tick the keys the folder is encrypted to, and list recipients no
     186              :    * key in the keyring answers to, so saving does not drop them silently.
     187              :    * @param recipients The folder's recipients, as listed in its `.gpg-id`.
     188              :    */
     189              :   void selectRecipients(const QStringList &recipients);
     190              : 
     191              :   /**
     192              :    * @brief Populate user list.
     193              :    * @param filter Optional filter text.
     194              :    */
     195              :   void populateList(const QString &filter = QString());
     196              :   /**
     197              :    * @brief Check if user passes filter.
     198              :    * @param user User to check.
     199              :    * @param filter Text filter.
     200              :    * @param nameFilter Regex filter.
     201              :    * @return true if user passes.
     202              :    */
     203              :   bool passesFilter(const UserInfo &user, const QString &filter,
     204              :                     const QRegularExpression &nameFilter) const;
     205              :   /**
     206              :    * @brief Check if GPG key is expired.
     207              :    * @param user User to check.
     208              :    * @return true if key is expired.
     209              :    */
     210              :   auto isUserExpired(const UserInfo &user) const -> bool;
     211              :   /**
     212              :    * @brief Build display text for user.
     213              :    * @param user User info.
     214              :    * @return Formatted text.
     215              :    */
     216              :   QString buildUserText(const UserInfo &user) const;
     217              :   /**
     218              :    * @brief Apply visual styling to user item.
     219              :    * @param item List item.
     220              :    * @param user User info.
     221              :    */
     222              :   void applyUserStyling(QListWidgetItem *item, const UserInfo &user) const;
     223              : };
     224              : 
     225              : #endif // SRC_USERSDIALOG_H_
        

Generated by: LCOV version 2.0-1